-
-
Notifications
You must be signed in to change notification settings - Fork 14.8k
Pin docs should mention pitfalls of generic code #62391
Copy link
Copy link
Open
Labels
A-async-awaitArea: Async & AwaitArea: Async & AwaitA-docsArea: Documentation for any part of the project, including the compiler, standard library, and toolsArea: Documentation for any part of the project, including the compiler, standard library, and toolsA-pinArea: PinArea: PinAsyncAwait-TriagedAsync-await issues that have been triaged during a working group meeting.Async-await issues that have been triaged during a working group meeting.C-enhancementCategory: An issue proposing an enhancement or a PR with one.Category: An issue proposing an enhancement or a PR with one.P-mediumMedium priorityMedium priorityT-langRelevant to the language teamRelevant to the language teamT-libs-apiRelevant to the library API team, which will review and decide on the PR/issue.Relevant to the library API team, which will review and decide on the PR/issue.
Metadata
Metadata
Assignees
Labels
A-async-awaitArea: Async & AwaitArea: Async & AwaitA-docsArea: Documentation for any part of the project, including the compiler, standard library, and toolsArea: Documentation for any part of the project, including the compiler, standard library, and toolsA-pinArea: PinArea: PinAsyncAwait-TriagedAsync-await issues that have been triaged during a working group meeting.Async-await issues that have been triaged during a working group meeting.C-enhancementCategory: An issue proposing an enhancement or a PR with one.Category: An issue proposing an enhancement or a PR with one.P-mediumMedium priorityMedium priorityT-langRelevant to the language teamRelevant to the language teamT-libs-apiRelevant to the library API team, which will review and decide on the PR/issue.Relevant to the library API team, which will review and decide on the PR/issue.
Type
Fields
Give feedbackNo fields configured for issues without a type.
The pin module docs currently have a note about implementing
Futurecombinators:However, this can be tricky in the presence of generics. Consider this code.
Here, we have an enum
DubiousDrop, whose destructor changes the enum variant. This type is slightly contrived but is perfectly safe (in fact, the entire containing module is safe).We then implement a simple pass-through future combinator called
MyWrapper, which simply delegates to a wrapped future using a pin projection. Unfortunately,MyWrapperis unsound - it constructs aPin<&mut F>without knowing ifFupholds thePinguarantees. OurDubiousDropenum explicitly does not uphold these guarantees - its destructor invalidates its memory by changing the enum variant, and it is notUnpin. Therefore, callingboomtriggers UB in safe code.AFAICT, there are two ways to prevent this kind of issue:
FuturebeUnpin(in this case, adding anF: Unpinbound toMyWrapper. This is the approach taken by types like futures::future::Select.Pinrequirements on their type.However, none of this appears to explicitly documented, and it's fairly subtle. I think it's important for the
std::pinandstd::pin::Pindocs to make these requirements very clear, as it seems to be somewhat of a footgun.