Skip to content
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

Slightly confusing grammar in pinning docs. #65868

Open
nathan-at-least opened this issue Oct 27, 2019 · 2 comments
Open

Slightly confusing grammar in pinning docs. #65868

nathan-at-least opened this issue Oct 27, 2019 · 2 comments
Labels
A-docs Area: Documentation for any part of the project, including the compiler, standard library, and tools C-enhancement Category: An issue proposing an enhancement or a PR with one. T-libs-api Relevant to the library API team, which will review and decide on the PR/issue.

Comments

@nathan-at-least
Copy link

Hi, I've just read the std::pin docs as part of learning std::future::Future and attempting to write my own combinator. This section is pretty dense for my first read, and only at the very end, when it mentioned Future combinators did I realize I had a misunderstanding through the entire reading due to this phrase in the projections section (link to rendered docs):

every field can be either projected to a pinned reference, or have pinning removed as part of the projection

At the end, the sentence that made me realize I had a misunderstanding is here:

But if your combinator contains any other data that does not need to be pinned, you can make those fields not structural and hence freely access them with a mutable reference even when you just have Pin<&mut Self> (such as in your own poll implementation).

My misunderstanding, on reading the first quote, was to believe that if any field is a pinned projection, then all other fields must also be pinned projections, or if any field is not, all other fields must not be. For me, if the first phrase said this instead, I think it would be clearer:

each field can either be projected to a pinned reference, or have pinning removed as part of the projection.

I'm a native English speaker, and I'm still not sure if the difference between my suggestion and the current text implies the technical difference I intend here, and I'm not sure if other readers might encounter a similar confusion. (Technical writing is hard!)

To really drive it home, maybe append the following sentence:

Fields may be projected to pinned or unpinned references independent of other fields.

I hope this helps make it easier for first-time readers to understand the projections and structural pinning section a bit better.

Thanks for your effort!

ps: Rust is awesome, and the core/std docs are excellent. ;-)

@jonas-schievink jonas-schievink added C-enhancement Category: An issue proposing an enhancement or a PR with one. A-docs Area: Documentation for any part of the project, including the compiler, standard library, and tools T-libs-api Relevant to the library API team, which will review and decide on the PR/issue. labels Oct 27, 2019
@Ixrec
Copy link
Contributor

Ixrec commented Oct 27, 2019

I agree that there's an ambiguity here, and that replacing that "every" with "each" will help slightly. Unfortunately, natural languages have never been strict about quantifier scopes, so although both forms of that sentence technically already imply that the decision is separate for each field, both are still ambiguous in practice.

I think the "independent of other fields" phrasing is probably more confusing than helpful, but I do agree that this justifies adding a few more words to decisively eliminate the ambiguity.

So I'd probably tweak that paragraph as follows:

Current wording:

It turns out that it is actually up to the author of the data structure to decide whether the pinned projection for a particular field turns Pin<&mut Struct> into Pin<&mut Field> or &mut Field. There are some constraints though, and the most important constraint is consistency: every field can be either projected to a pinned reference, or have pinning removed as part of the projection. If both are done for the same field, that will likely be unsound!

Suggested wording (changes/additions in bold):

It turns out that it is actually up to the author of the data structure to decide, for each field, whether that field's pinned projection turns Pin<&mut Struct> into Pin<&mut Field> or &mut Field. There are some constraints though, and the most important constraint is consistency: each field can be either projected to a pinned reference, or have pinning removed as part of the projection. It's fine for a struct to have some of its fields stay pinned and others remove pinning, but if both are done for the same field, that will likely be unsound!

(and yes, the existing docs are already amazing at clearly and concisely explaining a very subtle and novel corner of Rust)

@hkBst
Copy link
Member

hkBst commented Mar 10, 2025

Current wording from https://doc.rust-lang.org/nightly/std/pin/index.html is:

"""
It turns out that it’s up to the author of Struct to decide which type the “projection” should produce. The choice must be consistent though: if a pin is projected to a field in one place, then it should very likely not be exposed elsewhere without projecting the pin.

As the author of a data structure, you get to decide for each field whether pinning “propagates” to this field or not. Pinning that propagates is also called “structural”, because it follows the structure of the type.
"""

This already seems to include clearer text on the topic of this issue, so I think this can be closed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-docs Area: Documentation for any part of the project, including the compiler, standard library, and tools C-enhancement Category: An issue proposing an enhancement or a PR with one. T-libs-api Relevant to the library API team, which will review and decide on the PR/issue.
Projects
None yet
Development

No branches or pull requests

4 participants