rust-lang / rust

Empowering everyone to build reliable and efficient software.
https://www.rust-lang.org
Other
96.87k stars 12.51k forks source link

Slightly confusing grammar in pinning docs. #65868

Open nathan-at-least opened 4 years ago

nathan-at-least commented 4 years ago

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. ;-)

Ixrec commented 4 years ago

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)