mirror of https://github.com/rust-lang/rust.git
254 lines
10 KiB
Rust
254 lines
10 KiB
Rust
//@ edition: 2021
|
|
//@ run-rustfix
|
|
//@ rustfix-only-machine-applicable
|
|
//@ aux-build:migration_lint_macros.rs
|
|
#![feature(mut_ref)]
|
|
#![allow(incomplete_features, unused)]
|
|
#![deny(rust_2024_incompatible_pat)]
|
|
|
|
extern crate migration_lint_macros;
|
|
|
|
struct Foo<T>(T);
|
|
|
|
// Tests type equality in a way that avoids coercing `&&T` to `&T`.
|
|
trait Eq<T> {}
|
|
impl<T> Eq<T> for T {}
|
|
fn assert_type_eq<T, U: Eq<T>>(_: T, _: U) {}
|
|
|
|
fn main() {
|
|
let Foo(x) = &Foo(0);
|
|
assert_type_eq(x, &0u8);
|
|
|
|
let Foo(x) = &mut Foo(0);
|
|
assert_type_eq(x, &mut 0u8);
|
|
|
|
let Foo(mut x) = &Foo(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(x, 0u8);
|
|
|
|
let Foo(mut x) = &mut Foo(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(x, 0u8);
|
|
|
|
let Foo(ref x) = &Foo(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(x, &0u8);
|
|
|
|
let Foo(ref x) = &mut Foo(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(x, &0u8);
|
|
|
|
let &Foo(x) = &Foo(0);
|
|
assert_type_eq(x, 0u8);
|
|
|
|
let &mut Foo(x) = &mut Foo(0);
|
|
assert_type_eq(x, 0u8);
|
|
|
|
let &Foo(x) = &Foo(&0);
|
|
assert_type_eq(x, &0u8);
|
|
|
|
let &mut Foo(x) = &mut Foo(&0);
|
|
assert_type_eq(x, &0u8);
|
|
|
|
let Foo(&x) = &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(x, 0u8);
|
|
|
|
let Foo(&mut x) = &Foo(&mut 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(x, 0u8);
|
|
|
|
let Foo(&x) = &mut 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(x, 0u8);
|
|
|
|
let Foo(&mut x) = &mut Foo(&mut 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(x, 0u8);
|
|
|
|
if let Some(x) = &&&&&Some(&0u8) {
|
|
assert_type_eq(x, &&0u8);
|
|
}
|
|
|
|
if let Some(&x) = &&&&&Some(&0u8) {
|
|
//~^ 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(x, 0u8);
|
|
}
|
|
|
|
if let Some(&mut x) = &&&&&Some(&mut 0u8) {
|
|
//~^ 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(x, 0u8);
|
|
}
|
|
|
|
if let Some(&x) = &&&&&mut Some(&0u8) {
|
|
//~^ 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(x, 0u8);
|
|
}
|
|
|
|
if let Some(&mut Some(Some(x))) = &mut Some(&mut Some(&mut Some(0u8))) {
|
|
//~^ 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(x, &mut 0u8);
|
|
}
|
|
|
|
struct Struct<A, B, C> {
|
|
a: A,
|
|
b: B,
|
|
c: C,
|
|
}
|
|
|
|
let Struct { a, mut 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(b, 0u32);
|
|
|
|
let Struct { a: &a, b, ref c } = &Struct { a: &0, b: &0, c: &0 };
|
|
//~^ ERROR: binding modifiers and 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);
|
|
|
|
if let Struct { a: &Some(a), b: Some(&b), c: Some(c) } =
|
|
//~^ ERROR: reference patterns may only be written when the default binding mode is `move` in Rust 2024
|
|
//~| WARN: this changes meaning in Rust 2024
|
|
&(Struct { a: &Some(&0), b: &Some(&0), c: &Some(&0) })
|
|
{
|
|
assert_type_eq(a, &0u32);
|
|
assert_type_eq(b, 0u32);
|
|
assert_type_eq(c, &&0u32);
|
|
}
|
|
|
|
match &(Some(0), Some(0)) {
|
|
// The two patterns are the same syntactically, but because they're defined in different
|
|
// editions they don't mean the same thing.
|
|
(Some(mut x), migration_lint_macros::mixed_edition_pat!(y)) => {
|
|
//~^ ERROR: binding modifiers may only be written when the default binding mode is `move`
|
|
assert_type_eq(x, 0u32);
|
|
assert_type_eq(y, 0u32);
|
|
}
|
|
_ => {}
|
|
}
|
|
|
|
let [&mut [ref a]] = &mut [&mut &[0]];
|
|
//~^ ERROR: binding modifiers and 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);
|
|
|
|
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);
|
|
|
|
// Test that we use the correct message and suggestion style when pointing inside expansions.
|
|
let [migration_lint_macros::bind_ref!(a)] = &[0];
|
|
//~^ ERROR: binding modifiers may only be written when the default binding mode is `move`
|
|
assert_type_eq(a, &0u32);
|
|
|
|
// Test that we use the correct span when labeling a `&` whose subpattern is from an expansion.
|
|
let [&migration_lint_macros::bind_ref!(a)] = &[&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);
|
|
}
|