add more pattern migration tests

Most of these are meant to test possible future improvements, but since
they cover cases the existing test suite didn't, I figure including them
now may be helpful.

(cherry picked from commit f1e4d94fa4)
This commit is contained in:
dianne 2025-01-30 21:42:31 -08:00
parent c8e8068fe9
commit 8ee0fcb51b
3 changed files with 400 additions and 1 deletions

View File

@ -150,4 +150,93 @@ fn main() {
let &[&(_)] = &[&0];
//~^ ERROR: reference patterns may only be written when the default binding mode is `move` in Rust 2024
//~| WARN: this changes meaning in Rust 2024
// NB: Most of the following tests are for possible future improvements to migration suggestions
// Test removing multiple binding modifiers.
let Struct { a, b, c } = &Struct { a: 0, b: 0, c: 0 };
//~^ ERROR: binding modifiers may only be written when the default binding mode is `move` in Rust 2024
//~| WARN: this changes meaning in Rust 2024
assert_type_eq(a, &0u32);
assert_type_eq(c, &0u32);
// Test that we don't change bindings' modes when removing binding modifiers.
let &mut Struct { ref a, ref mut b, ref mut c } = &mut Struct { a: 0, b: 0, c: 0 };
//~^ ERROR: binding modifiers may only be written when the default binding mode is `move` in Rust 2024
//~| WARN: this changes meaning in Rust 2024
assert_type_eq(a, &0u32);
assert_type_eq(b, &mut 0u32);
assert_type_eq(c, &mut 0u32);
// Test removing multiple reference patterns of various mutabilities, plus a binding modifier.
let &mut &Struct { a: &[ref a], b: &mut [&[ref b]], ref c } = &mut &Struct { a: &[0], b: &mut [&[0]], c: 0 };
//~^ ERROR: reference patterns may only be written when the default binding mode is `move` in Rust 2024
//~| WARN: this changes meaning in Rust 2024
assert_type_eq(a, &0u32);
assert_type_eq(b, &0u32);
assert_type_eq(c, &0u32);
// Test that we don't change bindings' types when removing reference patterns.
let &Foo(&ref a) = &Foo(&0);
//~^ ERROR: reference patterns may only be written when the default binding mode is `move` in Rust 2024
//~| WARN: this changes meaning in Rust 2024
assert_type_eq(a, &0u32);
// Test that we don't change bindings' modes when adding reference paterns (caught early).
let &(&a, ref b, &[ref c], &mut [&mut (ref d, &[ref e])]) = &(&0, 0, &[0], &mut [&mut (0, &[0])]);
//~^ ERROR: reference patterns may only be written when the default binding mode is `move` in Rust 2024
//~| WARN: this changes meaning in Rust 2024
assert_type_eq(a, 0u32);
assert_type_eq(b, &0u32);
assert_type_eq(c, &0u32);
assert_type_eq(d, &0u32);
assert_type_eq(e, &0u32);
// Test that we don't change bindings' modes when adding reference patterns (caught late).
let &(ref a, &mut [ref b], &[mut c]) = &(0, &mut [0], &[0]);
//~^ ERROR: binding modifiers may only be written when the default binding mode is `move` in Rust 2024
//~| WARN: this changes meaning in Rust 2024
assert_type_eq(a, &0u32);
assert_type_eq(b, &0u32);
assert_type_eq(c, 0u32);
// Test featuring both additions and removals.
let &(&a, &mut (ref b, &[ref c])) = &(&0, &mut (0, &[0]));
//~^ ERROR: reference patterns may only be written when the default binding mode is `move` in Rust 2024
//~| WARN: this changes meaning in Rust 2024
assert_type_eq(a, 0u32);
assert_type_eq(b, &0u32);
assert_type_eq(c, &0u32);
// Test that bindings' subpatterns' modes are updated properly.
let &[mut a @ ref b] = &[0];
//~^ ERROR: binding modifiers may only be written when the default binding mode is `move` in Rust 2024
//~| WARN: this changes meaning in Rust 2024
assert_type_eq(a, 0u32);
assert_type_eq(b, &0u32);
// Test that bindings' subpatterns' modes are checked properly.
let &[ref a @ mut b] = &[0];
//~^ ERROR: binding modifiers may only be written when the default binding mode is `move` in Rust 2024
//~| WARN: this changes meaning in Rust 2024
assert_type_eq(a, &0u32);
assert_type_eq(b, 0u32);
// Test that we respect bindings' subpatterns' types when rewriting `&ref x` to `x`.
let [&Foo(&ref a @ ref b), &Foo(&ref c @ d)] = [&Foo(&0); 2];
//~^ ERROR: reference patterns may only be written when the default binding mode is `move` in Rust 2024
//~| WARN: this changes meaning in Rust 2024
assert_type_eq(a, &0u32);
assert_type_eq(b, &0u32);
assert_type_eq(c, &0u32);
assert_type_eq(d, 0u32);
// Test that we respect bindings' subpatterns' modes when rewriting `&ref x` to `x`.
let [&Foo(&ref a @ [ref b]), &Foo(&ref c @ [d])] = [&Foo(&[0]); 2];
//~^ ERROR: reference patterns may only be written when the default binding mode is `move` in Rust 2024
//~| WARN: this changes meaning in Rust 2024
assert_type_eq(a, &[0u32]);
assert_type_eq(b, &0u32);
assert_type_eq(c, &[0u32]);
assert_type_eq(d, 0u32);
}

View File

@ -150,4 +150,93 @@ fn main() {
let [&(_)] = &[&0];
//~^ ERROR: reference patterns may only be written when the default binding mode is `move` in Rust 2024
//~| WARN: this changes meaning in Rust 2024
// NB: Most of the following tests are for possible future improvements to migration suggestions
// Test removing multiple binding modifiers.
let Struct { ref a, ref b, c } = &Struct { a: 0, b: 0, c: 0 };
//~^ ERROR: binding modifiers may only be written when the default binding mode is `move` in Rust 2024
//~| WARN: this changes meaning in Rust 2024
assert_type_eq(a, &0u32);
assert_type_eq(c, &0u32);
// Test that we don't change bindings' modes when removing binding modifiers.
let Struct { ref a, ref mut b, c } = &mut Struct { a: 0, b: 0, c: 0 };
//~^ ERROR: binding modifiers may only be written when the default binding mode is `move` in Rust 2024
//~| WARN: this changes meaning in Rust 2024
assert_type_eq(a, &0u32);
assert_type_eq(b, &mut 0u32);
assert_type_eq(c, &mut 0u32);
// Test removing multiple reference patterns of various mutabilities, plus a binding modifier.
let Struct { a: &[ref a], b: &mut [[b]], c } = &mut &Struct { a: &[0], b: &mut [&[0]], c: 0 };
//~^ ERROR: reference patterns may only be written when the default binding mode is `move` in Rust 2024
//~| WARN: this changes meaning in Rust 2024
assert_type_eq(a, &0u32);
assert_type_eq(b, &0u32);
assert_type_eq(c, &0u32);
// Test that we don't change bindings' types when removing reference patterns.
let Foo(&ref a) = &Foo(&0);
//~^ ERROR: reference patterns may only be written when the default binding mode is `move` in Rust 2024
//~| WARN: this changes meaning in Rust 2024
assert_type_eq(a, &0u32);
// Test that we don't change bindings' modes when adding reference paterns (caught early).
let (&a, b, [c], [(d, [e])]) = &(&0, 0, &[0], &mut [&mut (0, &[0])]);
//~^ ERROR: reference patterns may only be written when the default binding mode is `move` in Rust 2024
//~| WARN: this changes meaning in Rust 2024
assert_type_eq(a, 0u32);
assert_type_eq(b, &0u32);
assert_type_eq(c, &0u32);
assert_type_eq(d, &0u32);
assert_type_eq(e, &0u32);
// Test that we don't change bindings' modes when adding reference patterns (caught late).
let (a, [b], [mut c]) = &(0, &mut [0], &[0]);
//~^ ERROR: binding modifiers may only be written when the default binding mode is `move` in Rust 2024
//~| WARN: this changes meaning in Rust 2024
assert_type_eq(a, &0u32);
assert_type_eq(b, &0u32);
assert_type_eq(c, 0u32);
// Test featuring both additions and removals.
let (&a, (b, &[ref c])) = &(&0, &mut (0, &[0]));
//~^ ERROR: reference patterns may only be written when the default binding mode is `move` in Rust 2024
//~| WARN: this changes meaning in Rust 2024
assert_type_eq(a, 0u32);
assert_type_eq(b, &0u32);
assert_type_eq(c, &0u32);
// Test that bindings' subpatterns' modes are updated properly.
let [mut a @ b] = &[0];
//~^ ERROR: binding modifiers may only be written when the default binding mode is `move` in Rust 2024
//~| WARN: this changes meaning in Rust 2024
assert_type_eq(a, 0u32);
assert_type_eq(b, &0u32);
// Test that bindings' subpatterns' modes are checked properly.
let [a @ mut b] = &[0];
//~^ ERROR: binding modifiers may only be written when the default binding mode is `move` in Rust 2024
//~| WARN: this changes meaning in Rust 2024
assert_type_eq(a, &0u32);
assert_type_eq(b, 0u32);
// Test that we respect bindings' subpatterns' types when rewriting `&ref x` to `x`.
let [Foo(&ref a @ ref b), Foo(&ref c @ d)] = [&Foo(&0); 2];
//~^ ERROR: reference patterns may only be written when the default binding mode is `move` in Rust 2024
//~| WARN: this changes meaning in Rust 2024
assert_type_eq(a, &0u32);
assert_type_eq(b, &0u32);
assert_type_eq(c, &0u32);
assert_type_eq(d, 0u32);
// Test that we respect bindings' subpatterns' modes when rewriting `&ref x` to `x`.
let [Foo(&ref a @ [ref b]), Foo(&ref c @ [d])] = [&Foo(&[0]); 2];
//~^ ERROR: reference patterns may only be written when the default binding mode is `move` in Rust 2024
//~| WARN: this changes meaning in Rust 2024
assert_type_eq(a, &[0u32]);
assert_type_eq(b, &0u32);
assert_type_eq(c, &[0u32]);
assert_type_eq(d, 0u32);
}

View File

@ -341,5 +341,226 @@ help: make the implied reference pattern explicit
LL | let &[&(_)] = &[&0];
| +
error: aborting due to 18 previous errors
error: binding modifiers may only be written when the default binding mode is `move` in Rust 2024
--> $DIR/migration_lint.rs:157:18
|
LL | let Struct { ref a, ref b, c } = &Struct { a: 0, b: 0, c: 0 };
| ^^^ ^^^ binding modifier not allowed under `ref` default binding mode
| |
| binding modifier not allowed under `ref` default binding mode
|
= warning: this changes meaning in Rust 2024
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/match-ergonomics.html>
note: matching on a reference type with a non-reference pattern changes the default binding mode
--> $DIR/migration_lint.rs:157:9
|
LL | let Struct { ref a, ref b, c } = &Struct { a: 0, b: 0, c: 0 };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ this matches on type `&_`
help: remove the unnecessary binding modifiers
|
LL - let Struct { ref a, ref b, c } = &Struct { a: 0, b: 0, c: 0 };
LL + let Struct { a, b, c } = &Struct { a: 0, b: 0, c: 0 };
|
error: binding modifiers may only be written when the default binding mode is `move` in Rust 2024
--> $DIR/migration_lint.rs:164:18
|
LL | let Struct { ref a, ref mut b, c } = &mut Struct { a: 0, b: 0, c: 0 };
| ^^^ ^^^^^^^ binding modifier not allowed under `ref mut` default binding mode
| |
| binding modifier not allowed under `ref mut` default binding mode
|
= warning: this changes meaning in Rust 2024
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/match-ergonomics.html>
note: matching on a reference type with a non-reference pattern changes the default binding mode
--> $DIR/migration_lint.rs:164:9
|
LL | let Struct { ref a, ref mut b, c } = &mut Struct { a: 0, b: 0, c: 0 };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ this matches on type `&mut _`
help: make the implied reference pattern and variable binding mode explicit
|
LL | let &mut Struct { ref a, ref mut b, ref mut c } = &mut Struct { a: 0, b: 0, c: 0 };
| ++++ +++++++
error: reference patterns may only be written when the default binding mode is `move` in Rust 2024
--> $DIR/migration_lint.rs:172:21
|
LL | let Struct { a: &[ref a], b: &mut [[b]], c } = &mut &Struct { a: &[0], b: &mut [&[0]], c: 0 };
| ^ ^^^^ reference pattern not allowed under `ref` default binding mode
| |
| reference pattern not allowed under `ref` default binding mode
|
= warning: this changes meaning in Rust 2024
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/match-ergonomics.html>
note: matching on a reference type with a non-reference pattern changes the default binding mode
--> $DIR/migration_lint.rs:172:9
|
LL | let Struct { a: &[ref a], b: &mut [[b]], c } = &mut &Struct { a: &[0], b: &mut [&[0]], c: 0 };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ this matches on type `&_`
help: make the implied reference patterns and variable binding modes explicit
|
LL | let &mut &Struct { a: &[ref a], b: &mut [&[ref b]], ref c } = &mut &Struct { a: &[0], b: &mut [&[0]], c: 0 };
| ++++++ + +++ +++
error: reference patterns may only be written when the default binding mode is `move` in Rust 2024
--> $DIR/migration_lint.rs:180:13
|
LL | let Foo(&ref a) = &Foo(&0);
| ^ reference pattern not allowed under `ref` default binding mode
|
= warning: this changes meaning in Rust 2024
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/match-ergonomics.html>
note: matching on a reference type with a non-reference pattern changes the default binding mode
--> $DIR/migration_lint.rs:180:9
|
LL | let Foo(&ref a) = &Foo(&0);
| ^^^^^^^^^^^ this matches on type `&_`
help: make the implied reference pattern explicit
|
LL | let &Foo(&ref a) = &Foo(&0);
| +
error: reference patterns may only be written when the default binding mode is `move` in Rust 2024
--> $DIR/migration_lint.rs:186:10
|
LL | let (&a, b, [c], [(d, [e])]) = &(&0, 0, &[0], &mut [&mut (0, &[0])]);
| ^ reference pattern not allowed under `ref` default binding mode
|
= warning: this changes meaning in Rust 2024
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/match-ergonomics.html>
note: matching on a reference type with a non-reference pattern changes the default binding mode
--> $DIR/migration_lint.rs:186:9
|
LL | let (&a, b, [c], [(d, [e])]) = &(&0, 0, &[0], &mut [&mut (0, &[0])]);
| ^^^^^^^^^^^^^^^^^^^^^^^^ this matches on type `&_`
help: make the implied reference patterns and variable binding modes explicit
|
LL | let &(&a, ref b, &[ref c], &mut [&mut (ref d, &[ref e])]) = &(&0, 0, &[0], &mut [&mut (0, &[0])]);
| + +++ + +++ ++++ ++++ +++ + +++
error: binding modifiers may only be written when the default binding mode is `move` in Rust 2024
--> $DIR/migration_lint.rs:196:19
|
LL | let (a, [b], [mut c]) = &(0, &mut [0], &[0]);
| ^^^ binding modifier not allowed under `ref` default binding mode
|
= warning: this changes meaning in Rust 2024
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/match-ergonomics.html>
note: matching on a reference type with a non-reference pattern changes the default binding mode
--> $DIR/migration_lint.rs:196:9
|
LL | let (a, [b], [mut c]) = &(0, &mut [0], &[0]);
| ^^^^^^^^^^^^^^^^^ this matches on type `&_`
help: make the implied reference patterns and variable binding modes explicit
|
LL | let &(ref a, &mut [ref b], &[mut c]) = &(0, &mut [0], &[0]);
| + +++ ++++ +++ +
error: reference patterns may only be written when the default binding mode is `move` in Rust 2024
--> $DIR/migration_lint.rs:204:10
|
LL | let (&a, (b, &[ref c])) = &(&0, &mut (0, &[0]));
| ^ ^ reference pattern not allowed under `ref` default binding mode
| |
| reference pattern not allowed under `ref` default binding mode
|
= warning: this changes meaning in Rust 2024
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/match-ergonomics.html>
note: matching on a reference type with a non-reference pattern changes the default binding mode
--> $DIR/migration_lint.rs:204:9
|
LL | let (&a, (b, &[ref c])) = &(&0, &mut (0, &[0]));
| ^^^^^^^^^^^^^^^^^^^ this matches on type `&_`
help: make the implied reference patterns and variable binding mode explicit
|
LL | let &(&a, &mut (ref b, &[ref c])) = &(&0, &mut (0, &[0]));
| + ++++ +++
error: binding modifiers may only be written when the default binding mode is `move` in Rust 2024
--> $DIR/migration_lint.rs:212:10
|
LL | let [mut a @ b] = &[0];
| ^^^ binding modifier not allowed under `ref` default binding mode
|
= warning: this changes meaning in Rust 2024
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/match-ergonomics.html>
note: matching on a reference type with a non-reference pattern changes the default binding mode
--> $DIR/migration_lint.rs:212:9
|
LL | let [mut a @ b] = &[0];
| ^^^^^^^^^^^ this matches on type `&_`
help: make the implied reference pattern and variable binding mode explicit
|
LL | let &[mut a @ ref b] = &[0];
| + +++
error: binding modifiers may only be written when the default binding mode is `move` in Rust 2024
--> $DIR/migration_lint.rs:219:14
|
LL | let [a @ mut b] = &[0];
| ^^^ binding modifier not allowed under `ref` default binding mode
|
= warning: this changes meaning in Rust 2024
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/match-ergonomics.html>
note: matching on a reference type with a non-reference pattern changes the default binding mode
--> $DIR/migration_lint.rs:219:9
|
LL | let [a @ mut b] = &[0];
| ^^^^^^^^^^^ this matches on type `&_`
help: make the implied reference pattern and variable binding mode explicit
|
LL | let &[ref a @ mut b] = &[0];
| + +++
error: reference patterns may only be written when the default binding mode is `move` in Rust 2024
--> $DIR/migration_lint.rs:226:14
|
LL | let [Foo(&ref a @ ref b), Foo(&ref c @ d)] = [&Foo(&0); 2];
| ^ ^ reference pattern not allowed under `ref` default binding mode
| |
| reference pattern not allowed under `ref` default binding mode
|
= warning: this changes meaning in Rust 2024
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/match-ergonomics.html>
note: matching on a reference type with a non-reference pattern changes the default binding mode
--> $DIR/migration_lint.rs:226:31
|
LL | let [Foo(&ref a @ ref b), Foo(&ref c @ d)] = [&Foo(&0); 2];
| ^^^^^^^^^^^^^^^ this matches on type `&_`
note: matching on a reference type with a non-reference pattern changes the default binding mode
--> $DIR/migration_lint.rs:226:10
|
LL | let [Foo(&ref a @ ref b), Foo(&ref c @ d)] = [&Foo(&0); 2];
| ^^^^^^^^^^^^^^^^^^^ this matches on type `&_`
help: make the implied reference patterns explicit
|
LL | let [&Foo(&ref a @ ref b), &Foo(&ref c @ d)] = [&Foo(&0); 2];
| + +
error: reference patterns may only be written when the default binding mode is `move` in Rust 2024
--> $DIR/migration_lint.rs:235:14
|
LL | let [Foo(&ref a @ [ref b]), Foo(&ref c @ [d])] = [&Foo(&[0]); 2];
| ^ ^ reference pattern not allowed under `ref` default binding mode
| |
| reference pattern not allowed under `ref` default binding mode
|
= warning: this changes meaning in Rust 2024
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/match-ergonomics.html>
note: matching on a reference type with a non-reference pattern changes the default binding mode
--> $DIR/migration_lint.rs:235:33
|
LL | let [Foo(&ref a @ [ref b]), Foo(&ref c @ [d])] = [&Foo(&[0]); 2];
| ^^^^^^^^^^^^^^^^^ this matches on type `&_`
note: matching on a reference type with a non-reference pattern changes the default binding mode
--> $DIR/migration_lint.rs:235:10
|
LL | let [Foo(&ref a @ [ref b]), Foo(&ref c @ [d])] = [&Foo(&[0]); 2];
| ^^^^^^^^^^^^^^^^^^^^^ this matches on type `&_`
help: make the implied reference patterns explicit
|
LL | let [&Foo(&ref a @ [ref b]), &Foo(&ref c @ [d])] = [&Foo(&[0]); 2];
| + +
error: aborting due to 29 previous errors