-
Notifications
You must be signed in to change notification settings - Fork 13.8k
Prevent downstream impl DerefMut for Pin<LocalType>
#145608
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Conversation
Prevent downstream impl DerefMut for Pin
This comment has been minimized.
This comment has been minimized.
We discussed this PR in today's standard library API meeting. Those present were on board with the approach, but it will be important to see a reasonably clean crater result and send PRs for any breakage, because not all downstream impls of DerefMut for Pin are necessarily unsound. The new implementation rules out correct as well as incorrect impls. Once crater is finished, we would like to do a libs-api FCP to surface this to the rest of the team. We noticed that the new pin::hidden::PinHelper type is now going to appear in diagnostics such as the pin-unsound-issue-85099-derefmut.stderr in this PR, but hopefully this mostly only happens when someone is doing funny business like writing their own DerefMut impl, and not for more typical use of Pin's methods and impls. |
Ok, let's see what crater says. But I don't think there are any valid use-cases for |
@craterbot check |
👌 Experiment ℹ️ Crater is a tool to run experiments across parts of the Rust ecosystem. Learn more |
017ed97
to
9bb2a3a
Compare
Updating this with some additional tests for error messages. I'm not worried about (See individual commits for how the error messages change.) |
A slightly different implementation seems to give somewhat better errors: But let's wait for crater before we think about that further. |
impl DerefMut for Pin<LocalType>
🚧 Experiment ℹ️ Crater is a tool to run experiments across parts of the Rust ecosystem. Learn more |
🎉 Experiment
|
🔔 This is now entering its final comment period, as per the review above. 🔔 |
I think excluding certain traits from fundamental makes sense as what could be missing. |
@rustbot labels +S-waiting-on-documentation @Darksonn, could you perhaps make a Reference PR here? We do cover cc @rust-lang/lang-docs @tshepang @PLeVasseur |
What are the expected changes to the reference here? This does not change anything about fundamental types in the language. The most I can think of would be "note: the standard library sometimes works around this by 'sealing' traits for fundamental types via indirection, e.g. But I feel like given the way it is implemented as an ordinary trait implementation, I would expect us to document this in the standard library on the impl, if at all. If we think this exception to the coherence rules for fundamental types is worth documenting, imo we should add a comment to the |
In my view, we should answer somewhere why As for where that should go, we've discussed recently that somewhat more in the way of details about lang-item types may need to live in the Reference, so I can see this here from that perspective. I could see the core library docs saying something about this too, of course. It's OK if both say something about it. The key point, though, is that we should say this clearly and normatively somewhere in our documentation. |
There are already a bunch of other examples of preventing downstream crates from implement traits on |
We document that. In this case, we're suppressing any documentation which would explain the behavior. |
I don't think whether we have rustdoc hacks to avoid showing how an impl is written should have any bearing on whether something goes in the reference or not. This PR doesn't change language semantics in any way. I do think it could possibly be confusing that people get errors that they "shouldn't" but the right place for that documentation to live would be the impl in std not the reference. The fact that Pin is a Lang item is somewhat besides the point IMO. it may be special to the language but this behaviour is not a special Pin thing. |
As mentioned, I'm happy as long as we document it somewhere.
|
Thanks for adding the doc comment. Left some editorial notes. |
1bda434
to
b50e330
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks; all looks great to me.
b50e330
to
d843323
Compare
This PR was rebased onto a different master commit. Here's a range-diff highlighting what actually changed. Rebasing is a normal part of keeping PRs up to date, so no action is needed—this note is just to help reviewers. |
d843323
to
5371b33
Compare
☔ The latest upstream changes (presumably #142771) made this pull request unmergeable. Please resolve the merge conflicts. |
The safety requirements for
PinCoerceUnsized
are essentially that the type does not have a maliciousDeref
orDerefMut
impl. However, thePin
type is fundamental, so the end-user can provide their own implementation ofDerefMut
forPin<&SomeLocalType>
, so it's possible forPin
to have a maliciousDerefMut
impl. This unsoundness is known as #85099.Unfortunately, this means that the implementation of
PinCoerceUnsized
forPin
is currently unsound. To fix that, modify the impl so that it becomes impossible for downstream crates to provide their own implementation ofDerefMut
forPin
by abusing a hidden struct that is not fundamental.This PR is a breaking change, but it fixes #85099. The PR supersedes #144896.
r? lcnr