Hacker News new | past | comments | ask | show | jobs | submit login

There are a couple of ways to interpret this code:

1. If this were public, or if you ever move out of the reference you get from that function, you would be violating the pin contract so this code would then be invalid.

2. Since its impossible to depend on the pin contract generically and this type doesn't actually depend on it, this is really just an indirect equivalent of implementing Unpin for the type, which is safe, so this code is valid.

I do think the second interpretation is correct (and I think its what the UCG group has decided), but this is a really nuanced conversation about the interpretation of unsafe code and validity. You started this thread by saying this is the reason pin is difficult for users: I am completely certain the median user is not in the weeds about what is and isn't valid unsafe code in pointless hypotheticals; the totally different set of idioms to get the same behavior for pinned references as for ordinary references is a much more pressing issue.




> I am completely certain the median user is not in the weeds about what is and isn't valid unsafe code in pointless hypotheticals; the totally different set of idioms to get the same behavior for pinned references as for ordinary references is a much more pressing issue.

I agree that the latter is indeed a pressing issue. But my point is that the former isn't about unsafe code so much as safe code: safe users of a concrete pinned target type may observe any number of different API surfaces, some of which allow modifying or swapping out various parts of the pinned object.

For a practical example of this, when the target type uses one of the pin-projection crates, it has a choice in which fields to denote as structural or non-structural, which affects how much the user can modify each field down the line. Indeed, a type could usefully choose make all of its fields non-structural, if only its address is externally referenced.

The pinning invariants simply don't fully constrain what the user of the target type can and cannot do, except for those constraints needed for the target type's own soundness.


In my next post, one of the major features I write about is pinned projection, and its true: for any type that supports pinned projection, it needs to decide for each field if pinning is transitive or not. This is different from how mutability works (mutability is always transitive).

There is a more elegant design which is basically reversed from pinning, but that's backward compatible with Rust. I also describe that in the next post. This pinned fields vs unpinned fields aspect of the behavior is the "necessary accidental complexity" of existing in the context of all in which we live and what came before us.


Upvoted just because the last sentence made me laugh. Perfect usage of that meme.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: