@@ -298,13 +298,7 @@ anyway is that the current behavior is unintuitive and surprising for users.
298
298
299
299
## Never setting default binding mode to ` ref mut ` behind ` & `
300
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.
301
+ ### We can't delay this choice
308
302
309
303
Note that while this is not a breaking change for edition 2021 and below, it
310
304
* would be breaking* to adopt the rest of this RFC without this change, and then
@@ -321,6 +315,45 @@ let &[[&mut a]] = &[&mut [42]];
321
315
322
316
Therefore, we * cannot* delay a decision on this matter.
323
317
318
+ ### Makes behavior more consistent
319
+
320
+ On all editions, when a structure pattern peels off a shared reference and the
321
+ default binding mode is already ` ref mut ` , the binding mode gets set to ` ref ` .
322
+ But when the binding mode is set to ` ref ` , and a mutable reference is peeled
323
+ off, the binding mode remains ` ref ` . In other words, immutability usually takes
324
+ precedence over mutability. This change, in addition to being generally useful,
325
+ makes the match ergonomics rules more consistent by ensuring that immutability
326
+ * always* takes precedence over mutability.
327
+
328
+ ### Ensures that a desirable property is preserved
329
+
330
+ The current match ergonomics rules uphold the following desirable property:
331
+
332
+ > An ` &mut ` pattern is accepted if and only if removing the pattern would allow
333
+ > obtaining an ` &mut ` value.
334
+
335
+ For example:
336
+
337
+ ``` rust
338
+ // ! All editions
339
+ let & mut a = & mut 42 ; // `a: i32`
340
+ let a = & mut 42 ; // `a: &mut i32`
341
+
342
+ let & [& mut a ] = & [& mut 42 ]; // `a: i32`
343
+ // let &[a] = &[&mut 42]; // ERROR, but…
344
+ let & [ref a ] = & [& mut 42 ]; // `a = &&mut i32` (so we did manage to obtain an `&mut i32` in some form)
345
+ ```
346
+
347
+ Adopting the "no ` ref mut ` behind ` & ` " rule ensures that this property continues
348
+ to hold for edition 2024:
349
+
350
+ ``` rust
351
+ // ! Edition ≥ 2024
352
+ let & [[& mut x ]] = & [& mut [42 ]]; // If we were allow this, with `x: i32` …
353
+ // let &[[x]] = &[&mut [42]]; // remove the `&mut` → ERROR, if the default binding mode is to be `ref mut`
354
+ // nothing we do will get us `&mut i32` in any form
355
+ ```
356
+
324
357
## ` & ` patterns matching against ` &mut `
325
358
326
359
There are several motivations for allowing this:
0 commit comments