I don't understand this API doc

This trait is implemented on-the-fly by the compiler for types Src and Self when the bits of any value of type Self are safely transmutable into a value of type Dst , in a given Context , notwithstanding whatever safety checks you have asked the compiler to Assume are satisfied.

"notwithstanding whatever ... are satisfied" - I'm not able to make sense of that English construction.
If I take this at face-value then it would imply "despite any satisfied assumptions... Self can be safely transmuted"? But why have any assumptions in that case? If the doc had been missing, I'd have guessed that the trait contract is that Self can be transmuted safely, given the context, and given the assumed safety checks (which may be "no assumptions").

1 Like

I think "notwithstanding" here means "except" rather than "despite". The transmute is possible, but you ask the compiler to assume some of the safety invariants are true rather than checking them for itself. (Disclaimer: IANAL)

I guess the choice of a negative-polarity word here is due to the presence of assumptions weakening the safety (and/or making the applicability of the conversion less general). Eg., in a complete sentence: "This transmute from Foo to Bar is safe, even though you asked the compiler to assume Bar is always padding-free." This would cause UB if Bar ever contained padding.

1 Like

The operative term here seems to be "IANAL". I do like the extensive API docs, but have the impression that the doc writers aim for a lawyerly precision which can have the opposite effect of obscuring the meaning (as may be the actual intention of lawyers when they use that kind of language).

My IANAL was primarily intended for humorous effect, as I'm neither a representative of T-opsem, nor a native speaker of English. :slight_smile: I don't think the docs actually aim for a lawyerly precision, but they do need to be detailed enough; otherwise, other people will complain that "we don't know whether corner case X or Y is guaranteed to work every midnight assuming a full moon".

1 Like

I've always struggled with the word "notwithstanding" notwithstanding the fact that I am native English speaker. Wait... Does that mean I'm not a native English speaker? Or that I don't struggle with the word? Or is it two negatives cancelling out? Is there a contrapositive hiding somewhere? Squirrel!

Clearly, they are using nightly English for documenting nightly features. Don't you see the warning running cargo doc?

warning: the feature `notwithstanding` is incomplete and may not be safe to use and/or cause reader crashes
= note: `#[warn(incomplete_features)]` on by default
14 Likes

I'm confused about your explanation. According to Wiktionary, "notwithstanding" means "despite", and not "except". Are you saying "notwithstanding" still can also mean "except"? Or that the documentation is incorrect? Or that the documentation is confusing and could be written in a clearer way by using "except"?

I have no idea what core::mem::BikeshedIntrinsicFrom is used for, but the way I understand the documentation, is that the assumptions have no effect on whether the trait is implemented on the fly by the compiler, but presumably the assumptions have some other effect. If that's not what it means, then maybe it should be rewritten?

1 Like

I'm saying that it's futile and useless to search for an unambiguous, 1-to-1 correspondence between natural language prose and exact operational semantics.

Wiktionary is certainly not an authority on Rust terminology in my mind. Not to mention that single, abstract words have rarely a precise, 100% equivalent synonym or explanation without additional context. What's "despite" for one person may reasonably be an "except" for another.

I don't really get why would anyone want to be so upset about such a subtle difference in phrasing. Especially given that the intention seems to be clear to you, I have no explanation as to why you would be splitting hair except for dramatic effect.

I don't think that's right as-is. Do note that the trait is generic. Given that this is a safety marker, and apparently an auto trait, the most reasonable way I think it should work is:

  • compiler looks at the source and destination types
  • compiler is able to prove a subset of safety invariants about transmuting between them (including: nothing, everything, or anything in between)
  • compiler implements the trait parameterized with those values of Assume that do not cause unsoundness. Eg., if the compiler can prove that the types can always be transmuted safely, then it implements BikeshedIntrinsicFrom<_, _, Assume::NOTHING> (and every other combination of assumption flags). If on the other hand the compiler can prove all invariants except that alignments will match, then it may only implement BikeshedIntrinsicFrom<_, _, Assume::ALIGNMENT>, delegating the soundness check to the user of the trait.

So, the assumptions should have an effect on both the implementation (implemented-ness?) of the trait and the safety/soundness of using it.

There are other problems with this documentation as well, which I assume will be worked out in the process of moving this from an experiment into a proper MCP or RFC:

  • It refers to a Dst type that doesn't appear anywhere in the signature
  • The Context type is important in some way, but there is no information about what the Context type should be in any given situation or how it affects the trait implementation
3 Likes

Yes, I noticed that too (probably an oversight/thinko/remainder from when the trait's parameters were permuted?), so there definitely is room for improvement.

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.