From f1e4d94fa4bd253c26610e8d79d5da8b52bad99f Mon Sep 17 00:00:00 2001 From: dianne Date: Thu, 30 Jan 2025 21:42:31 -0800 Subject: [PATCH] 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. --- .../migration_lint.fixed | 89 +++++++ .../migration_lint.rs | 89 +++++++ .../migration_lint.stderr | 223 +++++++++++++++++- 3 files changed, 400 insertions(+), 1 deletion(-) diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/migration_lint.fixed b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/migration_lint.fixed index 9ddc8912a5140..0a22e939496e5 100644 --- a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/migration_lint.fixed +++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/migration_lint.fixed @@ -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); } diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/migration_lint.rs b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/migration_lint.rs index bf5fd780404bc..7a6f2269d44a2 100644 --- a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/migration_lint.rs +++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/migration_lint.rs @@ -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); } diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/migration_lint.stderr b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/migration_lint.stderr index c36f92ecc7e08..191800df07a2e 100644 --- a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/migration_lint.stderr +++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/migration_lint.stderr @@ -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 +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 +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 +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 +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 +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 +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 +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 +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 +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 +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 +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