@@ -150,4 +150,93 @@ fn main() {
150150 let & [ & ( _) ] = & [ & 0 ] ;
151151 //~^ ERROR: reference patterns may only be written when the default binding mode is `move` in Rust 2024
152152 //~| WARN: this changes meaning in Rust 2024
153+
154+ // NB: Most of the following tests are for possible future improvements to migration suggestions
155+
156+ // Test removing multiple binding modifiers.
157+ let Struct { a, b, c } = & Struct { a : 0 , b : 0 , c : 0 } ;
158+ //~^ ERROR: binding modifiers may only be written when the default binding mode is `move` in Rust 2024
159+ //~| WARN: this changes meaning in Rust 2024
160+ assert_type_eq ( a, & 0u32 ) ;
161+ assert_type_eq ( c, & 0u32 ) ;
162+
163+ // Test that we don't change bindings' modes when removing binding modifiers.
164+ let & mut Struct { ref a, ref mut b, ref mut c } = & mut Struct { a : 0 , b : 0 , c : 0 } ;
165+ //~^ ERROR: binding modifiers may only be written when the default binding mode is `move` in Rust 2024
166+ //~| WARN: this changes meaning in Rust 2024
167+ assert_type_eq ( a, & 0u32 ) ;
168+ assert_type_eq ( b, & mut 0u32 ) ;
169+ assert_type_eq ( c, & mut 0u32 ) ;
170+
171+ // Test removing multiple reference patterns of various mutabilities, plus a binding modifier.
172+ let & mut & Struct { a : & [ ref a] , b : & mut [ & [ ref b] ] , ref c } = & mut & Struct { a : & [ 0 ] , b : & mut [ & [ 0 ] ] , c : 0 } ;
173+ //~^ ERROR: reference patterns may only be written when the default binding mode is `move` in Rust 2024
174+ //~| WARN: this changes meaning in Rust 2024
175+ assert_type_eq ( a, & 0u32 ) ;
176+ assert_type_eq ( b, & 0u32 ) ;
177+ assert_type_eq ( c, & 0u32 ) ;
178+
179+ // Test that we don't change bindings' types when removing reference patterns.
180+ let & Foo ( & ref a) = & Foo ( & 0 ) ;
181+ //~^ ERROR: reference patterns may only be written when the default binding mode is `move` in Rust 2024
182+ //~| WARN: this changes meaning in Rust 2024
183+ assert_type_eq ( a, & 0u32 ) ;
184+
185+ // Test that we don't change bindings' modes when adding reference paterns (caught early).
186+ let & ( & a, ref b, & [ ref c] , & mut [ & mut ( ref d, & [ ref e] ) ] ) = & ( & 0 , 0 , & [ 0 ] , & mut [ & mut ( 0 , & [ 0 ] ) ] ) ;
187+ //~^ ERROR: reference patterns may only be written when the default binding mode is `move` in Rust 2024
188+ //~| WARN: this changes meaning in Rust 2024
189+ assert_type_eq ( a, 0u32 ) ;
190+ assert_type_eq ( b, & 0u32 ) ;
191+ assert_type_eq ( c, & 0u32 ) ;
192+ assert_type_eq ( d, & 0u32 ) ;
193+ assert_type_eq ( e, & 0u32 ) ;
194+
195+ // Test that we don't change bindings' modes when adding reference patterns (caught late).
196+ let & ( ref a, & mut [ ref b] , & [ mut c] ) = & ( 0 , & mut [ 0 ] , & [ 0 ] ) ;
197+ //~^ ERROR: binding modifiers may only be written when the default binding mode is `move` in Rust 2024
198+ //~| WARN: this changes meaning in Rust 2024
199+ assert_type_eq ( a, & 0u32 ) ;
200+ assert_type_eq ( b, & 0u32 ) ;
201+ assert_type_eq ( c, 0u32 ) ;
202+
203+ // Test featuring both additions and removals.
204+ let & ( & a, & mut ( ref b, & [ ref c] ) ) = & ( & 0 , & mut ( 0 , & [ 0 ] ) ) ;
205+ //~^ ERROR: reference patterns may only be written when the default binding mode is `move` in Rust 2024
206+ //~| WARN: this changes meaning in Rust 2024
207+ assert_type_eq ( a, 0u32 ) ;
208+ assert_type_eq ( b, & 0u32 ) ;
209+ assert_type_eq ( c, & 0u32 ) ;
210+
211+ // Test that bindings' subpatterns' modes are updated properly.
212+ let & [ mut a @ ref b] = & [ 0 ] ;
213+ //~^ ERROR: binding modifiers may only be written when the default binding mode is `move` in Rust 2024
214+ //~| WARN: this changes meaning in Rust 2024
215+ assert_type_eq ( a, 0u32 ) ;
216+ assert_type_eq ( b, & 0u32 ) ;
217+
218+ // Test that bindings' subpatterns' modes are checked properly.
219+ let & [ ref a @ mut b] = & [ 0 ] ;
220+ //~^ ERROR: binding modifiers may only be written when the default binding mode is `move` in Rust 2024
221+ //~| WARN: this changes meaning in Rust 2024
222+ assert_type_eq ( a, & 0u32 ) ;
223+ assert_type_eq ( b, 0u32 ) ;
224+
225+ // Test that we respect bindings' subpatterns' types when rewriting `&ref x` to `x`.
226+ let [ & Foo ( & ref a @ ref b) , & Foo ( & ref c @ d) ] = [ & Foo ( & 0 ) ; 2 ] ;
227+ //~^ ERROR: reference patterns may only be written when the default binding mode is `move` in Rust 2024
228+ //~| WARN: this changes meaning in Rust 2024
229+ assert_type_eq ( a, & 0u32 ) ;
230+ assert_type_eq ( b, & 0u32 ) ;
231+ assert_type_eq ( c, & 0u32 ) ;
232+ assert_type_eq ( d, 0u32 ) ;
233+
234+ // Test that we respect bindings' subpatterns' modes when rewriting `&ref x` to `x`.
235+ let [ & Foo ( & ref a @ [ ref b] ) , & Foo ( & ref c @ [ d] ) ] = [ & Foo ( & [ 0 ] ) ; 2 ] ;
236+ //~^ ERROR: reference patterns may only be written when the default binding mode is `move` in Rust 2024
237+ //~| WARN: this changes meaning in Rust 2024
238+ assert_type_eq ( a, & [ 0u32 ] ) ;
239+ assert_type_eq ( b, & 0u32 ) ;
240+ assert_type_eq ( c, & [ 0u32 ] ) ;
241+ assert_type_eq ( d, 0u32 ) ;
153242}
0 commit comments