-
Notifications
You must be signed in to change notification settings - Fork 13.1k
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
Reconsider Rule 4E (early) for RFC 3627 #130501
Comments
Since Rule 4E (early), as proposed here, is edition-dependent and makes the operation of the other rules visible within patterns, this makes Rule 3 and Rule 5 edition-dependent also. So this proposal must either require adopting all the rules ahead of an edition or alternatively requiring a separate edition for adopting Rule 3 and Rule 5. |
Here's what we had said about this alternative in the 2024-06-26 lang design meeting (Match ergonomics, part 3):
|
I didn't know better at the time but this proposition doesn't actually change anything:
|
This example does not demonstrate that. Inlining, the example is: &[x]: &&mut [&mut T]
x: &mut &mut T //~ ERROR, RFC 3627
x: &&mut T //~ RFC 3627 I.e.: #[derive(Copy, Clone)]
struct T;
fn main() {
let &[_x] = &&mut [&mut T];
//~^ ERROR cannot borrow as mutable
} This case is an error in the current edition, so it does not show an edition-dependent change (it's backward compatible to make an error into a non-error). And Rule 1 and Rule 2 have no effect here. |
Oh apologies, I blindly trusted the solvers but it seems this is a case of borrow-checking that's not flagged. I have convinced myself that you're correct. |
Context
RFC3627 set out to improve some unintuitive edges of match ergonomics. The subtlest part involves fixing this case:
where a
&
pattern appears to remove two layers of references. T-lang agreed on the desireability of "eat-one-layer" instead, namely that a&
pattern should only ever remove one layer of reference.For that, the RFC proposes rule 2: "When a reference pattern matches against a reference, do not update the default binding mode". While this is arguably a straightforward change from an implementation perspective, let me show you that it does not appropriately solve the problem we set out to solve from a language perspective.
Issue
The reason is simple: there are two references at play in
&&T
; with rule 2 we match the pattern against the inner one of these. Some consequences (you can try these out in my online tool which can run both TC's and my solvers; just note that rule4-early has bugs when combined with rule 5):mut
orref
bindings:In short: rule 2 does "eat-one-layer" but eats the wrong layer. The fix is simply to eat the other one. In the language of RFC3627: "when the binding mode is ref or ref mut, match the pattern against the binding mode as if it was a reference"; this has been called "rule 4-early" in our discussions.
Edition
RFC3627 proposed to enable rules 1 and 2 over the edition. I propose to instead enable rules 1 and 4-early over the edition. Note that rule 4-early also replaces rule 4.
While I'm at it I would like to add a small additional rule, to enable fixing all the surprises:
move
, writingref
on a binding is an error.We can always revert to the previous behavior (i.e.
ref x
swallows a reference if it is inherited) if we wish to later.cc @traviscross
The text was updated successfully, but these errors were encountered: