Skip to content

Commit 1d1d1f4

Browse files
Expand on "no ref mut behind &"
1 parent 8e4b83c commit 1d1d1f4

File tree

1 file changed

+29
-8
lines changed

1 file changed

+29
-8
lines changed

text/3627-match-ergonomics-2024.md

Lines changed: 29 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -229,7 +229,7 @@ allows strictly more code to compile.)
229229
//! All editions (new)
230230

231231
let &[[a]] = &[&mut [42]];
232-
let _: &u8 = a;
232+
let _: &u8 = a; // previously `a` would be `&mut u8`, resulting in a move check error
233233

234234
let &[[a]] = &mut [&mut [42]];
235235
let _: &u8 = a;
@@ -289,6 +289,34 @@ The proposed rules for new editions uphold the following property:
289289
290290
In other words, the new match ergonomics rules are compositional.
291291

292+
## `mut` not resetting the binding mode
293+
294+
Admittedly, there is not much use for mutable by-reference bindings. This is
295+
true even outside of pattern matching; `let mut ident: &T = ...` is not commonly
296+
seen (though not entirely unknown either). The motivation for making this change
297+
anyway is that the current behavior is unintuitive and surprising for users.
298+
299+
## Never setting default binding mode to `ref mut` behind `&`
300+
301+
On all editions, when a structure pattern peels off a shared reference and the
302+
default binding mode is already `ref mut`, the binding mode gets set to `ref`.
303+
But when the binding mode is set to `ref`, and a mutable reference is peeled
304+
off, the binding mode remains `ref`. In other words, immutability usually takes
305+
precedence over mutability. This change, in addition to being generally useful,
306+
makes the match ergonomics rules more consistent by ensuring that immutability
307+
*always* takes precedence over mutability.
308+
309+
Note that while this is not a breaking change for edition 2021 and below, it
310+
*would be breaking* to adopt the rest of this RFC without this change, and then
311+
later adopt this change alone. Specifically, pattern matches like the following
312+
would break:
313+
314+
```rust
315+
let &[[&mut a]] = &[&mut [42]];
316+
```
317+
318+
Therefore, we *cannot* delay a decision on this matter.
319+
292320
## `&` patterns matching against `&mut`
293321

294322
There are several motivations for allowing this:
@@ -318,13 +346,6 @@ that prevents the default binding mode from being set to `ref mut` behind `&`.
318346
adding significant complexity to the variance rules, but I do believe it to be
319347
possible.
320348

321-
## `mut` not resetting the binding mode
322-
323-
Admittedly, there is not much use for mutable by-reference bindings. This is
324-
true even outside of pattern matching; `let mut ident: &T = ...` is not commonly
325-
seen (though not entirely unknown either). The motivation for making this change
326-
anyway is that the current behavior is unintuitive and surprising for users.
327-
328349
## Versus "eat-two-layers"
329350

330351
An alternative proposal would be to allow `&` and `&mut` patterns to reset the

0 commit comments

Comments
 (0)