Skip to content

Conversation

Darksonn
Copy link
Contributor

@Darksonn Darksonn commented Aug 19, 2025

The safety requirements for PinCoerceUnsized are essentially that the type does not have a malicious Deref or DerefMut impl. However, the Pin type is fundamental, so the end-user can provide their own implementation of DerefMut for Pin<&SomeLocalType>, so it's possible for Pin to have a malicious DerefMut impl. This unsoundness is known as #85099.

Unfortunately, this means that the implementation of PinCoerceUnsized for Pin is currently unsound. To fix that, modify the impl so that it becomes impossible for downstream crates to provide their own implementation of DerefMut for Pin 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

@Darksonn Darksonn added T-lang Relevant to the language team A-pin Area: Pin T-types Relevant to the types team, which will review and decide on the PR/issue. labels Aug 19, 2025
@Darksonn Darksonn requested a review from lcnr August 19, 2025 14:53
@rustbot rustbot added the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. label Aug 19, 2025
@Darksonn
Copy link
Contributor Author

It doesn't immediately look like error messages have regressed, but the docs have:

image

I'm going to push another commit to improve the docs to this:

image

I think it's reasonable in this case since the impls really are equivalent except for the orphan rules treatment.

@lcnr
Copy link
Contributor

lcnr commented Aug 19, 2025

I want to make sure I properly understand #85099 before merging this. I do think it's a very nice solution and gj for coming up with it!

I personally dislike "lying in the impl", even if it doesn't matter in practice. Gonna throw that question to @rust-lang/libs-api.

Let's crater

@bors try

rust-bors bot added a commit that referenced this pull request Aug 19, 2025
Prevent downstream impl DerefMut for Pin
@rust-bors

This comment has been minimized.

@dtolnay dtolnay added the I-libs-api-nominated Nominated for discussion during a libs-api team meeting. label Aug 19, 2025
@traviscross traviscross added I-lang-nominated Nominated for discussion during a lang team meeting. I-lang-radar Items that are on lang's radar and will need eventual work or consideration. P-lang-drag-1 Lang team prioritization drag level 1. https://rust-lang.zulipchat.com/#narrow/channel/410516-t-lang labels Aug 19, 2025
@dtolnay
Copy link
Member

dtolnay commented Aug 19, 2025

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.

@dtolnay dtolnay removed the I-libs-api-nominated Nominated for discussion during a libs-api team meeting. label Aug 19, 2025
@Darksonn
Copy link
Contributor Author

Ok, let's see what crater says. But I don't think there are any valid use-cases for impl DerefMut for Pin<P> for pointer types that aren't DerefMut.

@rust-bors
Copy link

rust-bors bot commented Aug 19, 2025

☀️ Try build successful (CI)
Build commit: c659ee1 (c659ee110de67e82444e4b6c8407c1a9af9c2cf6, parent: 8c32e313cccf7df531e2d49ffb8227bb92304aee)

@lcnr
Copy link
Contributor

lcnr commented Aug 19, 2025

@craterbot check

@craterbot
Copy link
Collaborator

👌 Experiment pr-145608 created and queued.
🤖 Automatically detected try build c659ee1
🔍 You can check out the queue and this experiment's details.

ℹ️ Crater is a tool to run experiments across parts of the Rust ecosystem. Learn more

@craterbot craterbot added S-waiting-on-crater Status: Waiting on a crater run to be completed. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Aug 19, 2025
@Darksonn
Copy link
Contributor Author

Darksonn commented Aug 19, 2025

Updating this with some additional tests for error messages. I'm not worried about PinHelper showing up in pin-unsound-issue-85099-derefmut.stderr, but that it also shows up in tests/ui/deref/pin-impl-deref.stderr is unfortunate.

(See individual commits for how the error messages change.)

@Darksonn
Copy link
Contributor Author

Darksonn commented Aug 19, 2025

A slightly different implementation seems to give somewhat better errors:

Darksonn@5e4d49a

But let's wait for crater before we think about that further.

@Darksonn Darksonn changed the title Prevent downstream impl DerefMut for Pin Prevent downstream impl DerefMut for Pin<LocalType> Aug 19, 2025
@traviscross traviscross removed the P-lang-drag-1 Lang team prioritization drag level 1. https://rust-lang.zulipchat.com/#narrow/channel/410516-t-lang label Aug 20, 2025
@craterbot craterbot added the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. label Sep 4, 2025
@jieyouxu

This comment was marked as off-topic.

@craterbot

This comment was marked as off-topic.

@jieyouxu
Copy link
Member

jieyouxu commented Sep 4, 2025

@craterbot run mode=check-only start=master#8c32e313cccf7df531e2d49ffb8227bb92304aee end=try#c659ee110de67e82444e4b6c8407c1a9af9c2cf6 crates=https://crater-reports.s3.amazonaws.com/pr-145608-1/retry-regressed-list.txt

@craterbot
Copy link
Collaborator

👌 Experiment pr-145608-2 created and queued.
🔍 You can check out the queue and this experiment's details.

ℹ️ Crater is a tool to run experiments across parts of the Rust ecosystem. Learn more

@craterbot craterbot added S-waiting-on-crater Status: Waiting on a crater run to be completed. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Sep 4, 2025
@craterbot
Copy link
Collaborator

🚧 Experiment pr-145608-2 is now running

ℹ️ Crater is a tool to run experiments across parts of the Rust ecosystem. Learn more

@craterbot
Copy link
Collaborator

🎉 Experiment pr-145608-2 is completed!
📊 0 regressed and 0 fixed (614 total)
📊 38 spurious results on the retry-regessed-list.txt, consider a retry1 if this is a significant amount.
📰 Open the summary report.

⚠️ If you notice any spurious failure please add them to the denylist!
ℹ️ Crater is a tool to run experiments across parts of the Rust ecosystem. Learn more

Footnotes

  1. re-run the experiment with crates=https://crater-reports.s3.amazonaws.com/pr-145608-2/retry-regressed-list.txt

@craterbot craterbot added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. and removed S-waiting-on-crater Status: Waiting on a crater run to be completed. labels Sep 7, 2025
@lcnr
Copy link
Contributor

lcnr commented Sep 8, 2025

lgtm and I agree that this is a good fix for #85099. Great job coming up with this solution. It's a lot nicer than adding some weird type system hack and has pretty much exactly the behavior we want.

r=me after FCP

My only open question is #145608 (comment) and whether we want the docs to lie. I guess @rust-lang/libs-api vibe is "yes, hiding the helper stuff is desirable".

@Darksonn
Copy link
Contributor Author

Darksonn commented Sep 8, 2025

I still think there is the open question of whether we should use the current implementation, or the one mentioned in #145608 (comment). It seems like the other implementation produces better error messages. I believe the behavior is identical.

@lcnr
Copy link
Contributor

lcnr commented Sep 8, 2025

if u go with the alternative impl we won't need to transmute anything 🤔 by changing the signature of DerefMutHelper::deref_mut to take Pin<Ptr>?

@Darksonn
Copy link
Contributor Author

Darksonn commented Sep 8, 2025

It isn't easy to declare that signature in the trait, because right now DerefMutHelper does not have access to Ptr. I would need to add a second associated type I think, so the transmute seems better IMO.

@traviscross traviscross added T-libs-api Relevant to the library API team, which will review and decide on the PR/issue. and removed T-types Relevant to the types team, which will review and decide on the PR/issue. labels Sep 10, 2025
@traviscross
Copy link
Contributor

This looks right to me. I propose we accept the behavior of this PR. As far as this pFCP goes, it would be OK to land the alternate implementation as well or @lcnr's proposed alternative without the transmute.

@rfcbot fcp merge

cc @rust-lang/types

@rust-rfcbot
Copy link
Collaborator

rust-rfcbot commented Sep 10, 2025

Team member @traviscross has proposed to merge this. The next step is review by the rest of the tagged team members:

No concerns currently listed.

Once a majority of reviewers approve (and at most 2 approvals are outstanding), this will enter its final comment period. If you spot a major issue that hasn't been raised at any point in this process, please speak up!

cc @rust-lang/lang-advisors: FCP proposed for lang, please feel free to register concerns.
See this document for info about what commands tagged team members can give me.

@rust-rfcbot rust-rfcbot added proposed-final-comment-period Proposed to merge/close by relevant subteam, see T-<team> label. Will enter FCP once signed off. disposition-merge This issue / PR is in PFCP or FCP with a disposition to merge it. labels Sep 10, 2025
@traviscross traviscross added P-lang-drag-1 Lang team prioritization drag level 1. https://rust-lang.zulipchat.com/#narrow/channel/410516-t-lang and removed P-lang-drag-2 Lang team prioritization drag level 2.https://rust-lang.zulipchat.com/#narrow/channel/410516-t-lang. labels Sep 10, 2025
@lcnr
Copy link
Contributor

lcnr commented Sep 10, 2025

ah btw, why does this FCP involve lang instead of only being a libs one 😅 😁

@traviscross
Copy link
Contributor

The type is special, given how we lean on it in the language. We take some interest in the core special types of the language. That's basically it.

@tmandry
Copy link
Member

tmandry commented Sep 10, 2025

Writing an impl like this doesn't make a lot of sense and I'm fine removing the ability, especially given the clean crater run.

Given the fact that Pin is #[fundamental] and the pin ergonomics work that makes Pin a lang item I think it makes sense to lang FCP this.

@rfcbot reviewed

@nikomatsakis
Copy link
Contributor

@rfcbot reviewed

So, I think this is very clever and we should land it. I also feel like this is an interesting case study -- there is obviously something missing at the language level that we ought to be expressing more clearly. But I'm not really clear on what it is. I'm also struggling a bit to express the requirements around this impl in 'plain english' terms.

matthiaskrgr added a commit to matthiaskrgr/rust that referenced this pull request Sep 10, 2025
Add tests for deref on pin

Tests split out from rust-lang#145608.

r? `@lcnr`
rust-timer added a commit that referenced this pull request Sep 11, 2025
Rollup merge of #146327 - Darksonn:pin-deref-tests, r=lcnr

Add tests for deref on pin

Tests split out from #145608.

r? `@lcnr`
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-pin Area: Pin disposition-merge This issue / PR is in PFCP or FCP with a disposition to merge it. I-lang-nominated Nominated for discussion during a lang team meeting. I-lang-radar Items that are on lang's radar and will need eventual work or consideration. P-lang-drag-1 Lang team prioritization drag level 1. https://rust-lang.zulipchat.com/#narrow/channel/410516-t-lang proposed-final-comment-period Proposed to merge/close by relevant subteam, see T-<team> label. Will enter FCP once signed off. S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-lang Relevant to the language team T-libs-api Relevant to the library API team, which will review and decide on the PR/issue.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

A Pin unsoundness involving an impl DerefMut for Pin<&dyn LocalTrait>