Keeping the RFC texts more accurate is alternative to or complement of having a spec. A pain point I have encountered many, many times is that the existing documentation about the language is incomplete and/or incorrect, not to mention explicitly non-normative.
Accepted RFCs are also not normative, even once completed (in large part because they are not kept up to date). However, they are still an invaluable resource for filling some of the holes in the documentation, or sussing out why something you've ran across differs from the Reference, say. That is, the RFCs are best source of information for some parts of the language.
But because they aren't reliably updated, you can't necessarily stop there. To get the full story you may have to read the RFC PR thread, read the tracking issue thread, search for RFCs that superseded this one, luck into finding any significant issues about the area of interest, and write a bunch of code to test out what the compiler actually does.
It's a lengthy process I've gone through more often than I wish, because I'm unaware of any better process to figure out what the compiler actually does in depth.
Below are a number of examples where the official documentation has been inadequate and the RFCs useful, but where the RFCs still fell short due to divergence or being superseded without the RFC being updated.
"That's the documentation process and/or specification process falling short, not a problem with RFCs" is a valid counterargument, provided that keeping those things up-to-date is a blocking requirement for significant changes (to stem this pattern from continuing to occur, once a spec exists ). Some mega-RFCs and many early-days RFCs are impractical to keep up to date in any case IMO (but could at least point the reader in the right direction).
Pattern binding modes
The reference is quite incomplete in terms of how binding modes work. In particular, it doesn't mention that the binding mode can be set to move
at all, much less detail when this happens. But people do run into it happening.
To the RFC! ...hmm, it seems the reference accurately reflects the text of the RFC. Heck, the RFC is even explicit about it:
Note that there is no exit from the ref
binding mode. This is because an &mut
inside of a &
is still a shared reference, and thus cannot be used to mutate the underlying value.
Also note that no transitions are taken when using an explicit ref
or ref mut
binding. The default binding mode only changes when matching a reference with a non-reference pattern.
What's the reality? From the middle of the 200+ comment tracking issue:
Changed from the RFC
The one change from the RFC was to "reset" the binding mode to "by value" whenever you encounter an explicit &
or &mut
pattern. This is to resolve the confusion described in #46688.
(While looking up the tracking issue, I also noticed the final comment contains another example of something from the RFC that does not compile, currently tracked by this separate issue it seems.)
I can only assume the reference is incomplete because it was based on the RFC text.
Understanding NLL in depth
This is a case where the RFC is invaluable. Nothing else explains how intrafunction borrow checking works without glossing over a ton of details, and usually conflating lifetime regions with value scopes, which the RFC takes care to avoid. It's also one of the only official places to find a definition or even mention of reborrowing (!).
That said, the RFC is arguably more useful to explain why certain things compile, versus fail to compile. Most programmers are more concerned about the latter. Leading to...
NLL Problem Case #3
People run into this one a lot, and allowing the code was one of the goals of the RFC, but it hasn't happened yet. But you can't read the RFC alone and find that out. No other documentation goes into borrow checking in enough depth to help you out either.
There's other deviations from the RFC too, but I couldn't tell you exactly what they are.
Two phase borrows
As far as I know it's not in any official documentation, so again one needs to fall back to the RFC to explain why certain code passes borrow check.
However, how two-phase borrows was actually implemented expanded beyond the RFC as outlined in this future compatibility lint issue. That lint was eventually abandoned (the warnings allowed) in order to land NLL stabilization.
I couldn't tell you exactly what two-phase borrows allows without doing a ton of work (experimentation and whatnot).
See also.
Breaking Changes
What should constitute a major breaking change? As far as I know, this topic also isn't covered in the standard documentation, so this is another case where the primary documentation is in an RFC. However, when it comes to traits, there's a distinction between fundamental and non-fundamental traits. Implementing non-fundamental traits is only a minor breaking change, it says.
But actually, it is a major breaking change if it's a blanket implementation.
Finally, RFC #1105 states that implementing any non-fundamental trait for an existing type is not a breaking change. This directly condradicts RFC #1023, which is entirely based around "blanket impls" being breaking changes. Regardless of whether the changes proposed to the orphan rules in this proposal are accepted, a blanket impl being a breaking change must be true today. Given that the compiler currently accepts impl From<Foo> for Vec<Foo>
, adding impl<T> From<T> for Vec<T>
must be considered a major breaking change.
As such, RFC #1105 is amended to remove the statement that implementing a non-fundamental trait is a minor breaking change, and states that adding any blanket impl for an existing trait is a major breaking change, using the definition of blanket impl given above.
Unfortunately RFC 1105, at least as it exists in the RFC book, was never updated. This can be problematic when people refer to RFC 1105 to reason about what is or isn't a major breaking change. That's a liability to Rust's stability guarantees, not just an inconvenience for Rust programmers.
This example illusrates that a spec alone is inadequate; if the RFCs aren't going to be updated, there needs to be an official place for things like this (and probably things like the governance RFCs) to be documented and kept up-to-date.
Others
I'm getting tired of writing these up and you've probably been tired of reading them for awhile, but other cases I've personally ran into where the reference was inadequate and the RFCs also incomplete or out of date include
Personally, the vast majority of my gripes would be satisfied by an accurate living spec. I'm very happy the spec RFC was accepted and deeply hope it comes to be.
In the meanwhile, I feel the OP's pain.