@@ -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