@@ -79,6 +79,23 @@ Match ergonomics works a little differently in edition 2024 and above.
7979// let (x, mut y) = &(true, false); // ERROR
8080```
8181
82+ ## ` & ` matches against ` &mut `
83+
84+ On all editions, ` & ` patterns can match against ` &mut ` references. On edition
85+ 2024 and above, this includes "inherited" references as described below.
86+
87+ ``` rust
88+ // ! All editions
89+ let & foo = & mut 42 ;
90+ let _ : u8 = foo ;
91+ ```
92+
93+ ``` rust
94+ // ! Edition ≥ 2024
95+ let [& foo ] = & mut [42 ];
96+ let _ : u8 = foo ;
97+ ```
98+
8299## Matching against inherited references
83100
84101In all editions, when you match against an ` & ` or ` &mut ` reference with the type
@@ -113,23 +130,6 @@ let [&x] = &[&42];
113130let _ : & u8 = x ;
114131```
115132
116- ## ` & ` matches against ` &mut `
117-
118- On all editions, ` & ` patterns can match against ` &mut ` references (on edition
119- 2024 and above, this includes "inherited" references).
120-
121- ``` rust
122- // ! All editions
123- let & foo = & mut 42 ;
124- let _ : u8 = foo ;
125- ```
126-
127- ``` rust
128- // ! Edition ≥ 2024
129- let [& foo ] = & mut [42 ];
130- let _ : u8 = foo ;
131- ```
132-
133133# Reference-level explanation
134134[ reference-level-explanation ] : #reference-level-explanation
135135
@@ -201,14 +201,18 @@ let _: u8 = a;
201201// let &b = 17; // ERROR
202202```
203203
204- If the default binding mode is ` ref ` , then ` &mut ` patterns are forbidden. If it
205- is by-value, then they have the same effect as on older editions.
204+ If the default binding mode is ` ref ` , then ` &mut ` patterns will not be able to
205+ match against it, so they will match structurally instead (preserving the
206+ binding mode).
206207
207208``` rust
208209// ! Edition ≥ 2024
209- // let [&mut x] = &[&mut 42]; // ERROR
210+ let [& mut x ] = & [& mut 42 ];
211+ let _ : & u8 = x ;
210212```
211213
214+ ` &mut ` patterns are otherwise unchanged.
215+
212216``` rust
213217// ! All editions
214218
@@ -490,25 +494,26 @@ fully compatible with proposals for "deref patterns", including allowing
490494question that would need to be resolved is whether and how deref patterns
491495(explicit or implicit) affect the default binding mode.
492496
493- ## Matching ` &mut ` behind ` & `
497+ ## Matching ` &mut ` directly behind ` & `
494498
495499There is one notable situation where match ergonomics cannot be used, and
496500explicit ` ref ` is required. This happens where ` &mut ` is nested behind ` & ` :
497501
498502``` rust
499503// No way to avoid the `ref`, even with this RFC
500- let & [ & mut ref x ] = & [ & mut 42 ] ; // x: &i32
504+ let && mut ref x = && mut 42 ; // x: &i32
501505```
502506
503507There are two strategies we could take to support this:
504508
505- - ` &mut ` patterns could match "behind" ` & ` . For example, in ` let [&mut x] = &[&mut 42]; ` ,
506- the ` &mut ` pattern would match the ` &mut ` reference in the scrutinee, leaving
507- ` & ` to be inherited and resulting in ` x: &i32 ` .
509+ - ` &mut ` patterns could “strip off” outer ` & ` . For example, in
510+ ` let &mut x = &&mut 42; ` , the ` &mut ` pattern would match the ` &mut ` reference
511+ in the scrutinee, leaving ` & ` to be inherited and resulting in ` x: &i32 ` .
508512 - This may not extend gracefully to future language features (partial borrows,
509- for example) as it relies on reference types forming a total order.
513+ for example) as it potentially relies on reference types forming a total
514+ order.
510515- The compiler could insert ` &mut ref ` in front of identifier patterns of type
511- ` &mut ` that are behind an ` & ` pattern. For example, ` let &[x] = &[ &mut 42]; `
512- would be transformed into ` let &[ &mut ref x] = &[ &mut 42] ; ` .
516+ ` &mut ` that are behind an ` & ` pattern. For example, ` let &x = &&mut 42; ` would
517+ be transformed into ` let &&mut ref x = &&mut 42; ` .
513518 - The full desugaring would be more complicated, as it would need to handle
514519 ` @ ` patterns.
0 commit comments