diff options
Diffstat (limited to 'tests')
187 files changed, 3666 insertions, 1487 deletions
diff --git a/tests/assembly/simd-intrinsic-mask-load.rs b/tests/assembly/simd-intrinsic-mask-load.rs index d537c143d36..b650e1cee30 100644 --- a/tests/assembly/simd-intrinsic-mask-load.rs +++ b/tests/assembly/simd-intrinsic-mask-load.rs @@ -18,6 +18,7 @@ pub trait Sized {} #[lang = "copy"] trait Copy {} +impl<T: ?Sized> Copy for *const T {} #[repr(simd)] pub struct i8x16([i8; 16]); diff --git a/tests/assembly/simd-intrinsic-mask-store.rs b/tests/assembly/simd-intrinsic-mask-store.rs index 5d4c00c3823..95a3b28b967 100644 --- a/tests/assembly/simd-intrinsic-mask-store.rs +++ b/tests/assembly/simd-intrinsic-mask-store.rs @@ -18,6 +18,7 @@ pub trait Sized {} #[lang = "copy"] trait Copy {} +impl<T: ?Sized> Copy for *mut T {} #[repr(simd)] pub struct i8x16([i8; 16]); diff --git a/tests/codegen/avr/avr-func-addrspace.rs b/tests/codegen/avr/avr-func-addrspace.rs index 70834707564..7f9a7e6e811 100644 --- a/tests/codegen/avr/avr-func-addrspace.rs +++ b/tests/codegen/avr/avr-func-addrspace.rs @@ -17,6 +17,7 @@ pub trait Sized {} #[lang = "copy"] pub trait Copy {} +impl<T: ?Sized> Copy for *const T {} #[lang = "receiver"] pub trait Receiver {} #[lang = "tuple_trait"] diff --git a/tests/codegen/cast-optimized.rs b/tests/codegen/cast-optimized.rs new file mode 100644 index 00000000000..313b2b4f0d6 --- /dev/null +++ b/tests/codegen/cast-optimized.rs @@ -0,0 +1,35 @@ +//@ compile-flags: -O -Z merge-functions=disabled +#![crate_type = "lib"] + +// This tests that LLVM can optimize based on the niches in the source or +// destination types for casts. + +// CHECK-LABEL: @u32_index +#[no_mangle] +pub fn u32_index(c: u32) -> [bool; 22] { + let mut array = [false; 22]; + + let index = 32 - c.leading_zeros(); + + // CHECK: call core::panicking::panic + array[index as usize] = true; + + array +} + +// CHECK-LABEL: @char_as_u32_index +#[no_mangle] +pub fn char_as_u32_index(c: char) -> [bool; 22] { + // CHECK: %[[B:.+]] = icmp ult i32 %c, 1114112 + // CHECK: call void @llvm.assume(i1 %[[B]]) + let c = c as u32; + + let mut array = [false; 22]; + + let index = 32 - c.leading_zeros(); + + // CHECK-NOT: call core::panicking::panic + array[index as usize] = true; + + array +} diff --git a/tests/codegen/clone-shims.rs b/tests/codegen/clone-shims.rs new file mode 100644 index 00000000000..06c959f9ee7 --- /dev/null +++ b/tests/codegen/clone-shims.rs @@ -0,0 +1,15 @@ +// Clone shims for aggregates are generated by just calling the Clone shims for all their members. +// Those calls generate a lot of unnecessary IR if the members are Copy. This test ensures that we +// optimize away those inner calls without needing to inline them. + +//@ compile-flags: -Cno-prepopulate-passes -Csymbol-mangling-version=v0 -Zinline-mir=no +#![crate_type = "lib"] + +pub type Test = (i32, i32, *const i32); +pub static TEST: fn(&Test) -> Test = <Test as core::clone::Clone>::clone; + +// CHECK-NOT: call <i32 as core::clone::Clone>::clone +// CHECK-NOT: call <*const i32 as core::clone::Clone>::clone +// CHECK: ; <(i32, i32, *const i32) as core::clone::Clone>::clone +// CHECK-NOT: call <i32 as core::clone::Clone>::clone +// CHECK-NOT: call <*const i32 as core::clone::Clone>::clone diff --git a/tests/codegen/emcripten-catch-unwind.rs b/tests/codegen/emcripten-catch-unwind.rs index 6cda8c6799f..35444db9558 100644 --- a/tests/codegen/emcripten-catch-unwind.rs +++ b/tests/codegen/emcripten-catch-unwind.rs @@ -16,6 +16,8 @@ trait Freeze {} #[lang = "copy"] trait Copy {} +impl<T> Copy for *mut T {} + #[rustc_intrinsic] fn size_of<T>() -> usize { loop {} diff --git a/tests/codegen/riscv-abi/riscv64-lp64-lp64f-lp64d-abi.rs b/tests/codegen/riscv-abi/riscv64-lp64-lp64f-lp64d-abi.rs index ed0af90aaaf..520192b5d59 100644 --- a/tests/codegen/riscv-abi/riscv64-lp64-lp64f-lp64d-abi.rs +++ b/tests/codegen/riscv-abi/riscv64-lp64-lp64f-lp64d-abi.rs @@ -18,6 +18,7 @@ impl Copy for i64 {} impl Copy for u64 {} impl Copy for f32 {} impl Copy for f64 {} +impl<T> Copy for *mut T {} // CHECK: define void @f_void() #[no_mangle] diff --git a/tests/codegen/sanitizer/kcfi/emit-type-metadata-trait-objects.rs b/tests/codegen/sanitizer/kcfi/emit-type-metadata-trait-objects.rs index fc4d570dc2e..c1967e55e75 100644 --- a/tests/codegen/sanitizer/kcfi/emit-type-metadata-trait-objects.rs +++ b/tests/codegen/sanitizer/kcfi/emit-type-metadata-trait-objects.rs @@ -15,6 +15,7 @@ trait Sized {} #[lang = "copy"] trait Copy {} +impl<T: ?Sized> Copy for &T {} #[lang = "receiver"] trait Receiver {} #[lang = "dispatch_from_dyn"] diff --git a/tests/codegen/try_identity.rs b/tests/codegen/try_identity.rs deleted file mode 100644 index 6a3a8a06e82..00000000000 --- a/tests/codegen/try_identity.rs +++ /dev/null @@ -1,34 +0,0 @@ -//@ compile-flags: -C no-prepopulate-passes -O -Z mir-opt-level=3 -Zunsound-mir-opts - -// Ensure that `x?` has no overhead on `Result<T, E>` due to identity `match`es in lowering. -// This requires inlining to trigger the MIR optimizations in `SimplifyArmIdentity`. - -#![crate_type = "lib"] - -type R = Result<u64, i32>; - -// This was written to the `?` from `try_trait`, but `try_trait_v2` uses a different structure, -// so the relevant desugar is copied inline in order to keep the test testing the same thing. -// FIXME(#85133): while this might be useful for `r#try!`, it would be nice to have a MIR -// optimization that picks up the `?` desugaring, as `SimplifyArmIdentity` does not. -#[no_mangle] -pub fn try_identity(x: R) -> R { - // CHECK: start: - // FIXME(JakobDegen): Broken by deaggregation change CHECK-NOT\: br {{.*}} - // CHECK ret void - let y = match into_result(x) { - Err(e) => return from_error(From::from(e)), - Ok(v) => v, - }; - Ok(y) -} - -#[inline] -fn into_result<T, E>(r: Result<T, E>) -> Result<T, E> { - r -} - -#[inline] -fn from_error<T, E>(e: E) -> Result<T, E> { - Err(e) -} diff --git a/tests/mir-opt/jump_threading.floats.JumpThreading.panic-abort.diff b/tests/mir-opt/jump_threading.floats.JumpThreading.panic-abort.diff new file mode 100644 index 00000000000..6ca37e96d29 --- /dev/null +++ b/tests/mir-opt/jump_threading.floats.JumpThreading.panic-abort.diff @@ -0,0 +1,59 @@ +- // MIR for `floats` before JumpThreading ++ // MIR for `floats` after JumpThreading + + fn floats() -> u32 { + let mut _0: u32; + let _1: f64; + let mut _2: bool; + let mut _3: bool; + let mut _4: f64; + scope 1 { + debug x => _1; + } + + bb0: { + StorageLive(_1); + StorageLive(_2); + _2 = const true; +- switchInt(move _2) -> [0: bb2, otherwise: bb1]; ++ goto -> bb1; + } + + bb1: { + _1 = const -0f64; + goto -> bb3; + } + + bb2: { + _1 = const 1f64; + goto -> bb3; + } + + bb3: { + StorageDead(_2); + StorageLive(_3); + StorageLive(_4); + _4 = _1; + _3 = Eq(move _4, const 0f64); + switchInt(move _3) -> [0: bb5, otherwise: bb4]; + } + + bb4: { + StorageDead(_4); + _0 = const 0_u32; + goto -> bb6; + } + + bb5: { + StorageDead(_4); + _0 = const 1_u32; + goto -> bb6; + } + + bb6: { + StorageDead(_3); + StorageDead(_1); + return; + } + } + diff --git a/tests/mir-opt/jump_threading.floats.JumpThreading.panic-unwind.diff b/tests/mir-opt/jump_threading.floats.JumpThreading.panic-unwind.diff new file mode 100644 index 00000000000..6ca37e96d29 --- /dev/null +++ b/tests/mir-opt/jump_threading.floats.JumpThreading.panic-unwind.diff @@ -0,0 +1,59 @@ +- // MIR for `floats` before JumpThreading ++ // MIR for `floats` after JumpThreading + + fn floats() -> u32 { + let mut _0: u32; + let _1: f64; + let mut _2: bool; + let mut _3: bool; + let mut _4: f64; + scope 1 { + debug x => _1; + } + + bb0: { + StorageLive(_1); + StorageLive(_2); + _2 = const true; +- switchInt(move _2) -> [0: bb2, otherwise: bb1]; ++ goto -> bb1; + } + + bb1: { + _1 = const -0f64; + goto -> bb3; + } + + bb2: { + _1 = const 1f64; + goto -> bb3; + } + + bb3: { + StorageDead(_2); + StorageLive(_3); + StorageLive(_4); + _4 = _1; + _3 = Eq(move _4, const 0f64); + switchInt(move _3) -> [0: bb5, otherwise: bb4]; + } + + bb4: { + StorageDead(_4); + _0 = const 0_u32; + goto -> bb6; + } + + bb5: { + StorageDead(_4); + _0 = const 1_u32; + goto -> bb6; + } + + bb6: { + StorageDead(_3); + StorageDead(_1); + return; + } + } + diff --git a/tests/mir-opt/jump_threading.rs b/tests/mir-opt/jump_threading.rs index de290c1ef44..e5d8525dcac 100644 --- a/tests/mir-opt/jump_threading.rs +++ b/tests/mir-opt/jump_threading.rs @@ -521,6 +521,16 @@ fn aggregate_copy() -> u32 { if c == 2 { b.0 } else { 13 } } +fn floats() -> u32 { + // CHECK-LABEL: fn floats( + // CHECK: switchInt( + + // Test for issue #128243, where float equality was assumed to be bitwise. + // When adding float support, it must be ensured that this continues working properly. + let x = if true { -0.0 } else { 1.0 }; + if x == 0.0 { 0 } else { 1 } +} + fn main() { // CHECK-LABEL: fn main( too_complex(Ok(0)); @@ -535,6 +545,7 @@ fn main() { disappearing_bb(7); aggregate(7); assume(7, false); + floats(); } // EMIT_MIR jump_threading.too_complex.JumpThreading.diff @@ -550,3 +561,4 @@ fn main() { // EMIT_MIR jump_threading.aggregate.JumpThreading.diff // EMIT_MIR jump_threading.assume.JumpThreading.diff // EMIT_MIR jump_threading.aggregate_copy.JumpThreading.diff +// EMIT_MIR jump_threading.floats.JumpThreading.diff diff --git a/tests/mir-opt/simplify_arm.id_try.SimplifyArmIdentity.diff b/tests/mir-opt/simplify_arm.id_try.SimplifyArmIdentity.diff deleted file mode 100644 index cff9afc38f0..00000000000 --- a/tests/mir-opt/simplify_arm.id_try.SimplifyArmIdentity.diff +++ /dev/null @@ -1,89 +0,0 @@ -- // MIR for `id_try` before SimplifyArmIdentity -+ // MIR for `id_try` after SimplifyArmIdentity - - fn id_try(_1: Result<u8, i32>) -> Result<u8, i32> { - debug r => _1; // in scope 0 at $DIR/simplify-arm.rs:+0:11: +0:12 - let mut _0: std::result::Result<u8, i32>; // return place in scope 0 at $DIR/simplify-arm.rs:+0:34: +0:49 - let _2: u8; // in scope 0 at $DIR/simplify-arm.rs:+1:9: +1:10 - let mut _3: std::result::Result<u8, i32>; // in scope 0 at $DIR/simplify-arm.rs:+1:19: +1:33 - let mut _4: std::result::Result<u8, i32>; // in scope 0 at $DIR/simplify-arm.rs:+1:31: +1:32 - let mut _5: isize; // in scope 0 at $DIR/simplify-arm.rs:+2:9: +2:15 - let _6: i32; // in scope 0 at $DIR/simplify-arm.rs:+2:13: +2:14 - let mut _7: !; // in scope 0 at $DIR/simplify-arm.rs:+2:19: +2:51 - let mut _8: i32; // in scope 0 at $DIR/simplify-arm.rs:+2:37: +2:50 - let mut _9: i32; // in scope 0 at $DIR/simplify-arm.rs:+2:48: +2:49 - let _10: u8; // in scope 0 at $DIR/simplify-arm.rs:+3:12: +3:13 - let mut _11: u8; // in scope 0 at $DIR/simplify-arm.rs:+5:8: +5:9 - scope 1 { - debug x => _2; // in scope 1 at $DIR/simplify-arm.rs:+1:9: +1:10 - } - scope 2 { - debug e => _6; // in scope 2 at $DIR/simplify-arm.rs:+2:13: +2:14 - scope 5 (inlined <i32 as From<i32>>::from) { // at $DIR/simplify-arm.rs:37:37: 37:50 - debug t => _9; // in scope 5 at $SRC_DIR/core/src/convert/mod.rs:LL:COL - } - scope 6 (inlined from_error::<u8, i32>) { // at $DIR/simplify-arm.rs:37:26: 37:51 - debug e => _8; // in scope 6 at $DIR/simplify-arm.rs:27:21: 27:22 - } - } - scope 3 { - debug v => _10; // in scope 3 at $DIR/simplify-arm.rs:+3:12: +3:13 - } - scope 4 (inlined into_result::<u8, i32>) { // at $DIR/simplify-arm.rs:36:19: 36:33 - debug r => _4; // in scope 4 at $DIR/simplify-arm.rs:23:22: 23:23 - } - - bb0: { - StorageLive(_2); // scope 0 at $DIR/simplify-arm.rs:+1:9: +1:10 - StorageLive(_3); // scope 0 at $DIR/simplify-arm.rs:+1:19: +1:33 - StorageLive(_4); // scope 0 at $DIR/simplify-arm.rs:+1:31: +1:32 - _4 = _1; // scope 0 at $DIR/simplify-arm.rs:+1:31: +1:32 - _3 = move _4; // scope 4 at $DIR/simplify-arm.rs:24:5: 24:6 - StorageDead(_4); // scope 0 at $DIR/simplify-arm.rs:+1:32: +1:33 - _5 = discriminant(_3); // scope 0 at $DIR/simplify-arm.rs:+1:19: +1:33 - switchInt(move _5) -> [0_isize: bb1, 1_isize: bb3, otherwise: bb2]; // scope 0 at $DIR/simplify-arm.rs:+1:13: +1:33 - } - - bb1: { - StorageLive(_10); // scope 0 at $DIR/simplify-arm.rs:+3:12: +3:13 - _10 = ((_3 as Ok).0: u8); // scope 0 at $DIR/simplify-arm.rs:+3:12: +3:13 - _2 = _10; // scope 3 at $DIR/simplify-arm.rs:+3:18: +3:19 - StorageDead(_10); // scope 0 at $DIR/simplify-arm.rs:+3:18: +3:19 - StorageDead(_3); // scope 0 at $DIR/simplify-arm.rs:+4:6: +4:7 - StorageLive(_11); // scope 1 at $DIR/simplify-arm.rs:+5:8: +5:9 - _11 = _2; // scope 1 at $DIR/simplify-arm.rs:+5:8: +5:9 - Deinit(_0); // scope 1 at $DIR/simplify-arm.rs:+5:5: +5:10 - ((_0 as Ok).0: u8) = move _11; // scope 1 at $DIR/simplify-arm.rs:+5:5: +5:10 - discriminant(_0) = 0; // scope 1 at $DIR/simplify-arm.rs:+5:5: +5:10 - StorageDead(_11); // scope 1 at $DIR/simplify-arm.rs:+5:9: +5:10 - StorageDead(_2); // scope 0 at $DIR/simplify-arm.rs:+6:1: +6:2 - goto -> bb4; // scope 0 at $DIR/simplify-arm.rs:+6:2: +6:2 - } - - bb2: { - unreachable; // scope 0 at $DIR/simplify-arm.rs:+1:19: +1:33 - } - - bb3: { - StorageLive(_6); // scope 0 at $DIR/simplify-arm.rs:+2:13: +2:14 - _6 = ((_3 as Err).0: i32); // scope 0 at $DIR/simplify-arm.rs:+2:13: +2:14 - StorageLive(_8); // scope 2 at $DIR/simplify-arm.rs:+2:37: +2:50 - StorageLive(_9); // scope 2 at $DIR/simplify-arm.rs:+2:48: +2:49 - _9 = _6; // scope 2 at $DIR/simplify-arm.rs:+2:48: +2:49 - _8 = move _9; // scope 5 at $SRC_DIR/core/src/convert/mod.rs:LL:COL - StorageDead(_9); // scope 2 at $DIR/simplify-arm.rs:+2:49: +2:50 - ((_0 as Err).0: i32) = move _8; // scope 6 at $DIR/simplify-arm.rs:28:9: 28:10 - Deinit(_0); // scope 6 at $DIR/simplify-arm.rs:28:5: 28:11 - discriminant(_0) = 1; // scope 6 at $DIR/simplify-arm.rs:28:5: 28:11 - StorageDead(_8); // scope 2 at $DIR/simplify-arm.rs:+2:50: +2:51 - StorageDead(_6); // scope 0 at $DIR/simplify-arm.rs:+2:50: +2:51 - StorageDead(_3); // scope 0 at $DIR/simplify-arm.rs:+4:6: +4:7 - StorageDead(_2); // scope 0 at $DIR/simplify-arm.rs:+6:1: +6:2 - goto -> bb4; // scope 0 at $DIR/simplify-arm.rs:+6:2: +6:2 - } - - bb4: { - return; // scope 0 at $DIR/simplify-arm.rs:+6:2: +6:2 - } - } - diff --git a/tests/mir-opt/simplify_arm.id_try.SimplifyBranchSame.diff b/tests/mir-opt/simplify_arm.id_try.SimplifyBranchSame.diff deleted file mode 100644 index 9d38b93508c..00000000000 --- a/tests/mir-opt/simplify_arm.id_try.SimplifyBranchSame.diff +++ /dev/null @@ -1,89 +0,0 @@ -- // MIR for `id_try` before SimplifyBranchSame -+ // MIR for `id_try` after SimplifyBranchSame - - fn id_try(_1: Result<u8, i32>) -> Result<u8, i32> { - debug r => _1; // in scope 0 at $DIR/simplify-arm.rs:+0:11: +0:12 - let mut _0: std::result::Result<u8, i32>; // return place in scope 0 at $DIR/simplify-arm.rs:+0:34: +0:49 - let _2: u8; // in scope 0 at $DIR/simplify-arm.rs:+1:9: +1:10 - let mut _3: std::result::Result<u8, i32>; // in scope 0 at $DIR/simplify-arm.rs:+1:19: +1:33 - let mut _4: std::result::Result<u8, i32>; // in scope 0 at $DIR/simplify-arm.rs:+1:31: +1:32 - let mut _5: isize; // in scope 0 at $DIR/simplify-arm.rs:+2:9: +2:15 - let _6: i32; // in scope 0 at $DIR/simplify-arm.rs:+2:13: +2:14 - let mut _7: !; // in scope 0 at $DIR/simplify-arm.rs:+2:19: +2:51 - let mut _8: i32; // in scope 0 at $DIR/simplify-arm.rs:+2:37: +2:50 - let mut _9: i32; // in scope 0 at $DIR/simplify-arm.rs:+2:48: +2:49 - let _10: u8; // in scope 0 at $DIR/simplify-arm.rs:+3:12: +3:13 - let mut _11: u8; // in scope 0 at $DIR/simplify-arm.rs:+5:8: +5:9 - scope 1 { - debug x => _2; // in scope 1 at $DIR/simplify-arm.rs:+1:9: +1:10 - } - scope 2 { - debug e => _6; // in scope 2 at $DIR/simplify-arm.rs:+2:13: +2:14 - scope 5 (inlined <i32 as From<i32>>::from) { // at $DIR/simplify-arm.rs:37:37: 37:50 - debug t => _9; // in scope 5 at $SRC_DIR/core/src/convert/mod.rs:LL:COL - } - scope 6 (inlined from_error::<u8, i32>) { // at $DIR/simplify-arm.rs:37:26: 37:51 - debug e => _8; // in scope 6 at $DIR/simplify-arm.rs:27:21: 27:22 - } - } - scope 3 { - debug v => _10; // in scope 3 at $DIR/simplify-arm.rs:+3:12: +3:13 - } - scope 4 (inlined into_result::<u8, i32>) { // at $DIR/simplify-arm.rs:36:19: 36:33 - debug r => _4; // in scope 4 at $DIR/simplify-arm.rs:23:22: 23:23 - } - - bb0: { - StorageLive(_2); // scope 0 at $DIR/simplify-arm.rs:+1:9: +1:10 - StorageLive(_3); // scope 0 at $DIR/simplify-arm.rs:+1:19: +1:33 - StorageLive(_4); // scope 0 at $DIR/simplify-arm.rs:+1:31: +1:32 - _4 = _1; // scope 0 at $DIR/simplify-arm.rs:+1:31: +1:32 - _3 = move _4; // scope 4 at $DIR/simplify-arm.rs:24:5: 24:6 - StorageDead(_4); // scope 0 at $DIR/simplify-arm.rs:+1:32: +1:33 - _5 = discriminant(_3); // scope 0 at $DIR/simplify-arm.rs:+1:19: +1:33 - switchInt(move _5) -> [0_isize: bb1, 1_isize: bb3, otherwise: bb2]; // scope 0 at $DIR/simplify-arm.rs:+1:13: +1:33 - } - - bb1: { - StorageLive(_10); // scope 0 at $DIR/simplify-arm.rs:+3:12: +3:13 - _10 = ((_3 as Ok).0: u8); // scope 0 at $DIR/simplify-arm.rs:+3:12: +3:13 - _2 = _10; // scope 3 at $DIR/simplify-arm.rs:+3:18: +3:19 - StorageDead(_10); // scope 0 at $DIR/simplify-arm.rs:+3:18: +3:19 - StorageDead(_3); // scope 0 at $DIR/simplify-arm.rs:+4:6: +4:7 - StorageLive(_11); // scope 1 at $DIR/simplify-arm.rs:+5:8: +5:9 - _11 = _2; // scope 1 at $DIR/simplify-arm.rs:+5:8: +5:9 - Deinit(_0); // scope 1 at $DIR/simplify-arm.rs:+5:5: +5:10 - ((_0 as Ok).0: u8) = move _11; // scope 1 at $DIR/simplify-arm.rs:+5:5: +5:10 - discriminant(_0) = 0; // scope 1 at $DIR/simplify-arm.rs:+5:5: +5:10 - StorageDead(_11); // scope 1 at $DIR/simplify-arm.rs:+5:9: +5:10 - StorageDead(_2); // scope 0 at $DIR/simplify-arm.rs:+6:1: +6:2 - goto -> bb4; // scope 0 at $DIR/simplify-arm.rs:+6:2: +6:2 - } - - bb2: { - unreachable; // scope 0 at $DIR/simplify-arm.rs:+1:19: +1:33 - } - - bb3: { - StorageLive(_6); // scope 0 at $DIR/simplify-arm.rs:+2:13: +2:14 - _6 = ((_3 as Err).0: i32); // scope 0 at $DIR/simplify-arm.rs:+2:13: +2:14 - StorageLive(_8); // scope 2 at $DIR/simplify-arm.rs:+2:37: +2:50 - StorageLive(_9); // scope 2 at $DIR/simplify-arm.rs:+2:48: +2:49 - _9 = _6; // scope 2 at $DIR/simplify-arm.rs:+2:48: +2:49 - _8 = move _9; // scope 5 at $SRC_DIR/core/src/convert/mod.rs:LL:COL - StorageDead(_9); // scope 2 at $DIR/simplify-arm.rs:+2:49: +2:50 - ((_0 as Err).0: i32) = move _8; // scope 6 at $DIR/simplify-arm.rs:28:9: 28:10 - Deinit(_0); // scope 6 at $DIR/simplify-arm.rs:28:5: 28:11 - discriminant(_0) = 1; // scope 6 at $DIR/simplify-arm.rs:28:5: 28:11 - StorageDead(_8); // scope 2 at $DIR/simplify-arm.rs:+2:50: +2:51 - StorageDead(_6); // scope 0 at $DIR/simplify-arm.rs:+2:50: +2:51 - StorageDead(_3); // scope 0 at $DIR/simplify-arm.rs:+4:6: +4:7 - StorageDead(_2); // scope 0 at $DIR/simplify-arm.rs:+6:1: +6:2 - goto -> bb4; // scope 0 at $DIR/simplify-arm.rs:+6:2: +6:2 - } - - bb4: { - return; // scope 0 at $DIR/simplify-arm.rs:+6:2: +6:2 - } - } - diff --git a/tests/mir-opt/simplify_arm.rs b/tests/mir-opt/simplify_arm.rs deleted file mode 100644 index 5d9c31121dd..00000000000 --- a/tests/mir-opt/simplify_arm.rs +++ /dev/null @@ -1,50 +0,0 @@ -// skip-filecheck -//@ compile-flags: -Z mir-opt-level=3 -Zunsound-mir-opts -// EMIT_MIR simplify_arm.id.SimplifyArmIdentity.diff -// EMIT_MIR simplify_arm.id.SimplifyBranchSame.diff -// EMIT_MIR simplify_arm.id_result.SimplifyArmIdentity.diff -// EMIT_MIR simplify_arm.id_result.SimplifyBranchSame.diff -// EMIT_MIR simplify_arm.id_try.SimplifyArmIdentity.diff -// EMIT_MIR simplify_arm.id_try.SimplifyBranchSame.diff - -//@ ignore-test This pass is broken since deaggregation changed - -fn id(o: Option<u8>) -> Option<u8> { - match o { - Some(v) => Some(v), - None => None, - } -} - -fn id_result(r: Result<u8, i32>) -> Result<u8, i32> { - match r { - Ok(x) => Ok(x), - Err(y) => Err(y), - } -} - -fn into_result<T, E>(r: Result<T, E>) -> Result<T, E> { - r -} - -fn from_error<T, E>(e: E) -> Result<T, E> { - Err(e) -} - -// This was written to the `?` from `try_trait`, but `try_trait_v2` uses a different structure, -// so the relevant desugar is copied inline in order to keep the test testing the same thing. -// FIXME(#85133): while this might be useful for `r#try!`, it would be nice to have a MIR -// optimization that picks up the `?` desugaring, as `SimplifyArmIdentity` does not. -fn id_try(r: Result<u8, i32>) -> Result<u8, i32> { - let x = match into_result(r) { - Err(e) => return from_error(From::from(e)), - Ok(v) => v, - }; - Ok(x) -} - -fn main() { - id(None); - id_result(Ok(4)); - id_try(Ok(4)); -} diff --git a/tests/mir-opt/simplify_arm_identity.rs b/tests/mir-opt/simplify_arm_identity.rs deleted file mode 100644 index 79395b312ac..00000000000 --- a/tests/mir-opt/simplify_arm_identity.rs +++ /dev/null @@ -1,26 +0,0 @@ -// skip-filecheck -// Checks that `SimplifyArmIdentity` is not applied if enums have incompatible layouts. -// Regression test for issue #66856. -// -//@ compile-flags: -Zmir-opt-level=3 -// EMIT_MIR_FOR_EACH_BIT_WIDTH - -//@ ignore-test This pass is broken since deaggregation changed - -enum Src { - Foo(u8), - Bar, -} - -enum Dst { - Foo(u8), -} - -// EMIT_MIR simplify_arm_identity.main.SimplifyArmIdentity.diff -fn main() { - let e: Src = Src::Foo(0); - let _: Dst = match e { - Src::Foo(x) => Dst::Foo(x), - Src::Bar => Dst::Foo(0), - }; -} diff --git a/tests/mir-opt/simplify_try_if_let.rs b/tests/mir-opt/simplify_try_if_let.rs deleted file mode 100644 index 98df9a54abb..00000000000 --- a/tests/mir-opt/simplify_try_if_let.rs +++ /dev/null @@ -1,44 +0,0 @@ -// skip-filecheck -//@ compile-flags: -Zmir-opt-level=1 -Zunsound-mir-opts -//@ ignore-test -// FIXME: the pass is unsound and causes ICEs in the MIR validator - -// EMIT_MIR simplify_try_if_let.{impl#0}-append.SimplifyArmIdentity.diff - -use std::ptr::NonNull; - -pub struct LinkedList { - head: Option<NonNull<Node>>, - tail: Option<NonNull<Node>>, -} - -pub struct Node { - next: Option<NonNull<Node>>, -} - -impl LinkedList { - pub fn new() -> Self { - Self { head: None, tail: None } - } - - pub fn append(&mut self, other: &mut Self) { - match self.tail { - None => {} - Some(mut tail) => { - // `as_mut` is okay here because we have exclusive access to the entirety - // of both lists. - if let Some(other_head) = other.head.take() { - unsafe { - tail.as_mut().next = Some(other_head); - } - } - } - } - } -} - -fn main() { - let mut one = LinkedList::new(); - let mut two = LinkedList::new(); - one.append(&mut two); -} diff --git a/tests/mir-opt/simplify_try_if_let.{impl#0}-append.SimplifyArmIdentity.diff b/tests/mir-opt/simplify_try_if_let.{impl#0}-append.SimplifyArmIdentity.diff deleted file mode 100644 index 11f6b533741..00000000000 --- a/tests/mir-opt/simplify_try_if_let.{impl#0}-append.SimplifyArmIdentity.diff +++ /dev/null @@ -1,104 +0,0 @@ -- // MIR for `<impl at $DIR/simplify_try_if_let.rs:15:1: 34:2>::append` before SimplifyArmIdentity -+ // MIR for `<impl at $DIR/simplify_try_if_let.rs:15:1: 34:2>::append` after SimplifyArmIdentity - - fn <impl at $DIR/simplify_try_if_let.rs:15:1: 34:2>::append(_1: &mut LinkedList, _2: &mut LinkedList) -> () { - debug self => _1; // in scope 0 at $DIR/simplify_try_if_let.rs:20:19: 20:28 - debug other => _2; // in scope 0 at $DIR/simplify_try_if_let.rs:20:30: 20:35 - let mut _0: (); // return place in scope 0 at $DIR/simplify_try_if_let.rs:20:48: 20:48 - let mut _3: isize; // in scope 0 at $DIR/simplify_try_if_let.rs:22:13: 22:17 - let mut _4: std::ptr::NonNull<Node>; // in scope 0 at $DIR/simplify_try_if_let.rs:23:18: 23:26 - let mut _5: std::option::Option<std::ptr::NonNull<Node>>; // in scope 0 at $DIR/simplify_try_if_let.rs:26:43: 26:60 - let mut _6: &mut std::option::Option<std::ptr::NonNull<Node>>; // in scope 0 at $DIR/simplify_try_if_let.rs:26:43: 26:53 - let mut _7: isize; // in scope 0 at $DIR/simplify_try_if_let.rs:26:24: 26:40 - let mut _9: std::option::Option<std::ptr::NonNull<Node>>; // in scope 0 at $DIR/simplify_try_if_let.rs:28:46: 28:62 - let mut _10: std::ptr::NonNull<Node>; // in scope 0 at $DIR/simplify_try_if_let.rs:28:51: 28:61 - let mut _11: &mut Node; // in scope 0 at $DIR/simplify_try_if_let.rs:28:25: 28:38 - let mut _12: &mut std::ptr::NonNull<Node>; // in scope 0 at $DIR/simplify_try_if_let.rs:28:25: 28:29 - scope 1 { - debug tail => _4; // in scope 1 at $DIR/simplify_try_if_let.rs:23:18: 23:26 - let _8: std::ptr::NonNull<Node>; // in scope 1 at $DIR/simplify_try_if_let.rs:26:29: 26:39 - scope 2 { -- debug other_head => _8; // in scope 2 at $DIR/simplify_try_if_let.rs:26:29: 26:39 -+ debug other_head => ((_9 as Some).0: std::ptr::NonNull<Node>); // in scope 2 at $DIR/simplify_try_if_let.rs:26:29: 26:39 - scope 3 { - } - } - } - - bb0: { - _3 = discriminant(((*_1).1: std::option::Option<std::ptr::NonNull<Node>>)); // scope 0 at $DIR/simplify_try_if_let.rs:22:13: 22:17 - switchInt(move _3) -> [0_isize: bb3, 1_isize: bb1, otherwise: bb2]; // scope 0 at $DIR/simplify_try_if_let.rs:22:13: 22:17 - } - - bb1: { - StorageLive(_4); // scope 0 at $DIR/simplify_try_if_let.rs:23:18: 23:26 - _4 = ((((*_1).1: std::option::Option<std::ptr::NonNull<Node>>) as Some).0: std::ptr::NonNull<Node>); // scope 0 at $DIR/simplify_try_if_let.rs:23:18: 23:26 - StorageLive(_5); // scope 1 at $DIR/simplify_try_if_let.rs:26:43: 26:60 - StorageLive(_6); // scope 1 at $DIR/simplify_try_if_let.rs:26:43: 26:53 - _6 = &mut ((*_2).0: std::option::Option<std::ptr::NonNull<Node>>); // scope 1 at $DIR/simplify_try_if_let.rs:26:43: 26:53 - _5 = Option::<NonNull<Node>>::take(move _6) -> bb4; // scope 1 at $DIR/simplify_try_if_let.rs:26:43: 26:60 - // mir::Constant - // + span: $DIR/simplify_try_if_let.rs:26:54: 26:58 - // + literal: Const { ty: for<'r> fn(&'r mut std::option::Option<std::ptr::NonNull<Node>>) -> std::option::Option<std::ptr::NonNull<Node>> {std::option::Option::<std::ptr::NonNull<Node>>::take}, val: Value(Scalar(<ZST>)) } - } - - bb2: { - unreachable; // scope 0 at $DIR/simplify_try_if_let.rs:21:15: 21:24 - } - - bb3: { - _0 = const (); // scope 0 at $DIR/simplify_try_if_let.rs:22:21: 22:24 - goto -> bb9; // scope 0 at $DIR/simplify_try_if_let.rs:21:9: 32:10 - } - - bb4: { - StorageDead(_6); // scope 1 at $DIR/simplify_try_if_let.rs:26:59: 26:60 - _7 = discriminant(_5); // scope 1 at $DIR/simplify_try_if_let.rs:26:24: 26:40 - switchInt(move _7) -> [1_isize: bb6, otherwise: bb5]; // scope 1 at $DIR/simplify_try_if_let.rs:26:24: 26:40 - } - - bb5: { - _0 = const (); // scope 1 at $DIR/simplify_try_if_let.rs:26:17: 30:18 - goto -> bb8; // scope 1 at $DIR/simplify_try_if_let.rs:26:17: 30:18 - } - - bb6: { - StorageLive(_8); // scope 1 at $DIR/simplify_try_if_let.rs:26:29: 26:39 - _8 = ((_5 as Some).0: std::ptr::NonNull<Node>); // scope 1 at $DIR/simplify_try_if_let.rs:26:29: 26:39 - StorageLive(_9); // scope 3 at $DIR/simplify_try_if_let.rs:28:46: 28:62 -- StorageLive(_10); // scope 3 at $DIR/simplify_try_if_let.rs:28:51: 28:61 -- _10 = _8; // scope 3 at $DIR/simplify_try_if_let.rs:28:51: 28:61 -- ((_9 as Some).0: std::ptr::NonNull<Node>) = move _10; // scope 3 at $DIR/simplify_try_if_let.rs:28:46: 28:62 -- discriminant(_9) = 1; // scope 3 at $DIR/simplify_try_if_let.rs:28:46: 28:62 -- StorageDead(_10); // scope 3 at $DIR/simplify_try_if_let.rs:28:61: 28:62 -+ _9 = move _5; // scope 3 at $DIR/simplify_try_if_let.rs:28:46: 28:62 - StorageLive(_11); // scope 3 at $DIR/simplify_try_if_let.rs:28:25: 28:38 - StorageLive(_12); // scope 3 at $DIR/simplify_try_if_let.rs:28:25: 28:29 - _12 = &mut _4; // scope 3 at $DIR/simplify_try_if_let.rs:28:25: 28:29 - _11 = NonNull::<Node>::as_mut(move _12) -> bb7; // scope 3 at $DIR/simplify_try_if_let.rs:28:25: 28:38 - // mir::Constant - // + span: $DIR/simplify_try_if_let.rs:28:30: 28:36 - // + literal: Const { ty: for<'r> unsafe fn(&'r mut std::ptr::NonNull<Node>) -> &'r mut Node {std::ptr::NonNull::<Node>::as_mut}, val: Value(Scalar(<ZST>)) } - } - - bb7: { - StorageDead(_12); // scope 3 at $DIR/simplify_try_if_let.rs:28:37: 28:38 - ((*_11).0: std::option::Option<std::ptr::NonNull<Node>>) = move _9; // scope 3 at $DIR/simplify_try_if_let.rs:28:25: 28:62 - StorageDead(_9); // scope 3 at $DIR/simplify_try_if_let.rs:28:61: 28:62 - StorageDead(_11); // scope 3 at $DIR/simplify_try_if_let.rs:28:62: 28:63 - _0 = const (); // scope 3 at $DIR/simplify_try_if_let.rs:27:21: 29:22 - StorageDead(_8); // scope 1 at $DIR/simplify_try_if_let.rs:30:17: 30:18 - goto -> bb8; // scope 1 at $DIR/simplify_try_if_let.rs:26:17: 30:18 - } - - bb8: { - StorageDead(_5); // scope 1 at $DIR/simplify_try_if_let.rs:31:13: 31:14 - StorageDead(_4); // scope 0 at $DIR/simplify_try_if_let.rs:31:13: 31:14 - goto -> bb9; // scope 0 at $DIR/simplify_try_if_let.rs:21:9: 32:10 - } - - bb9: { - return; // scope 0 at $DIR/simplify_try_if_let.rs:33:6: 33:6 - } - } - diff --git a/tests/run-make/README.md b/tests/run-make/README.md index a6c1b4b7db7..40359903473 100644 --- a/tests/run-make/README.md +++ b/tests/run-make/README.md @@ -41,3 +41,8 @@ The setup for the `rmake.rs` version is a 3-stage process: [`run_make_support`]: ../../src/tools/run-make-support [extern_prelude]: https://doc.rust-lang.org/reference/names/preludes.html#extern-prelude + +### Formatting + +Note that files under `tests/` are not formatted by `./x fmt`, +use `rustfmt tests/path/to/file.rs` to format a specific file if desired. diff --git a/tests/run-make/c-unwind-abi-catch-lib-panic/Makefile b/tests/run-make/c-unwind-abi-catch-lib-panic/Makefile deleted file mode 100644 index 2bb8d42495d..00000000000 --- a/tests/run-make/c-unwind-abi-catch-lib-panic/Makefile +++ /dev/null @@ -1,35 +0,0 @@ -# Exercise unwinding a panic. This catches a panic across an FFI boundary and downcasts it into an integer. The Rust code that panics is in a separate crate. -# See https://github.com/rust-lang/rust/commit/baf227ea0c1e07fc54395a51e4b3881d701180cb - -# ignore-cross-compile -# needs-unwind -include ../tools.mk - -all: archive - # Compile `main.rs`, which will link into our library, and run it. - $(RUSTC) main.rs - $(call RUN,main) - -ifdef IS_MSVC -archive: add.o panic.o - # Now, create an archive using these two objects. - $(AR) crus $(TMPDIR)/add.lib $(TMPDIR)/add.o $(TMPDIR)/panic.o -else -archive: add.o panic.o - # Now, create an archive using these two objects. - $(AR) crus $(TMPDIR)/libadd.a $(TMPDIR)/add.o $(TMPDIR)/panic.o -endif - -# Compile `panic.rs` into an object file. -# -# Note that we invoke `rustc` directly, so we may emit an object rather -# than an archive. We'll do that later. -panic.o: - $(BARE_RUSTC) $(RUSTFLAGS) \ - --out-dir $(TMPDIR) \ - --emit=obj panic.rs - -# Compile `add.c` into an object file. -add.o: - $(call COMPILE_OBJ,$(TMPDIR)/add.o,add.c) - diff --git a/tests/run-make/c-unwind-abi-catch-lib-panic/rmake.rs b/tests/run-make/c-unwind-abi-catch-lib-panic/rmake.rs new file mode 100644 index 00000000000..62e1748b6fb --- /dev/null +++ b/tests/run-make/c-unwind-abi-catch-lib-panic/rmake.rs @@ -0,0 +1,36 @@ +// Exercise unwinding a panic. This catches a panic across an FFI (foreign function interface) +// boundary and downcasts it into an integer. +// The Rust code that panics is in a separate crate. +// See https://github.com/rust-lang/rust/commit/baf227ea0c1e07fc54395a51e4b3881d701180cb + +//@ ignore-cross-compile +// Reason: the compiled binary is executed +//@ needs-unwind +// Reason: this test exercises unwinding a panic + +use run_make_support::{cc, is_msvc, llvm_ar, run, rustc, static_lib_name}; + +fn main() { + // Compile `add.c` into an object file. + if is_msvc() { + cc().arg("-c").out_exe("add").input("add.c").run(); + } else { + cc().arg("-v").arg("-c").out_exe("add.o").input("add.c").run(); + }; + + // Compile `panic.rs` into an object file. + // Note that we invoke `rustc` directly, so we may emit an object rather + // than an archive. We'll do that later. + rustc().emit("obj").input("panic.rs").run(); + + // Now, create an archive using these two objects. + if is_msvc() { + llvm_ar().obj_to_ar().args(&[&static_lib_name("add"), "add.obj", "panic.o"]).run(); + } else { + llvm_ar().obj_to_ar().args(&[&static_lib_name("add"), "add.o", "panic.o"]).run(); + }; + + // Compile `main.rs`, which will link into our library, and run it. + rustc().input("main.rs").run(); + run("main"); +} diff --git a/tests/run-make/compiler-rt-works-on-mingw/Makefile b/tests/run-make/compiler-rt-works-on-mingw/Makefile deleted file mode 100644 index 74917570a01..00000000000 --- a/tests/run-make/compiler-rt-works-on-mingw/Makefile +++ /dev/null @@ -1,9 +0,0 @@ -include ../tools.mk - -# only-windows-gnu - -all: - $(CXX) foo.cpp -c -o $(TMPDIR)/foo.o - $(AR) crus $(TMPDIR)/libfoo.a $(TMPDIR)/foo.o - $(RUSTC) foo.rs -lfoo -lstdc++ - $(call RUN,foo) diff --git a/tests/run-make/compiler-rt-works-on-mingw/rmake.rs b/tests/run-make/compiler-rt-works-on-mingw/rmake.rs new file mode 100644 index 00000000000..f1b41f96312 --- /dev/null +++ b/tests/run-make/compiler-rt-works-on-mingw/rmake.rs @@ -0,0 +1,15 @@ +// `compiler-rt` ("runtime") is a suite of LLVM features compatible with rustc. +// After building it was enabled on Windows-gnu in #29874, this test is a basic smoke test to +// check if building and linking to it can work at all. +// See https://github.com/rust-lang/rust/pull/29478 + +//@ only-windows-gnu + +use run_make_support::{cxx, is_msvc, llvm_ar, run, rustc, static_lib_name}; + +fn main() { + cxx().input("foo.cpp").arg("-c").out_exe("foo.o").run(); + llvm_ar().obj_to_ar().output_input(static_lib_name("foo"), "foo.o").run(); + rustc().input("foo.rs").arg("-lfoo").arg("-lstdc++").run(); + run("foo"); +} diff --git a/tests/run-make/dump-ice-to-disk/Makefile b/tests/run-make/dump-ice-to-disk/Makefile deleted file mode 100644 index 23006fc09e2..00000000000 --- a/tests/run-make/dump-ice-to-disk/Makefile +++ /dev/null @@ -1,10 +0,0 @@ -include ../tools.mk - -# ignore-windows - -export RUSTC := $(RUSTC_ORIGINAL) -export LD_LIBRARY_PATH := $(HOST_RPATH_DIR) -export TMPDIR := $(TMPDIR) - -all: - bash check.sh diff --git a/tests/run-make/dump-ice-to-disk/check.sh b/tests/run-make/dump-ice-to-disk/check.sh deleted file mode 100644 index ff6e4be35af..00000000000 --- a/tests/run-make/dump-ice-to-disk/check.sh +++ /dev/null @@ -1,64 +0,0 @@ -#!/bin/sh - -# Default nightly behavior (write ICE to current directory) -# FIXME(estebank): these are failing on CI, but passing locally. -# $RUSTC src/lib.rs -Z treat-err-as-bug=1 1>$TMPDIR/rust-test-default.log 2>&1 -# default=$(cat ./rustc-ice-*.txt | wc -l) -# rm ./rustc-ice-*.txt - -# Explicit directory set -export RUSTC_ICE=$TMPDIR -$RUSTC src/lib.rs -Z treat-err-as-bug=1 1>$TMPDIR/rust-test-default-set.log 2>&1 -default_set=$(cat $TMPDIR/rustc-ice-*.txt | wc -l) -content=$(cat $TMPDIR/rustc-ice-*.txt) -# Ensure that the ICE dump path doesn't contain `:` because they cause problems on Windows -windows_safe=$(echo rustc-ice-*.txt | grep ':') -if [ ! -z "$windows_safe" ]; then - exit 1 -fi - -rm $TMPDIR/rustc-ice-*.txt -RUST_BACKTRACE=short $RUSTC src/lib.rs -Z treat-err-as-bug=1 1>$TMPDIR/rust-test-short.log 2>&1 -short=$(cat $TMPDIR/rustc-ice-*.txt | wc -l) -rm $TMPDIR/rustc-ice-*.txt -RUST_BACKTRACE=full $RUSTC src/lib.rs -Z treat-err-as-bug=1 1>$TMPDIR/rust-test-full.log 2>&1 -full=$(cat $TMPDIR/rustc-ice-*.txt | wc -l) -rm $TMPDIR/rustc-ice-*.txt - -# Explicitly disabling ICE dump -export RUSTC_ICE=0 -$RUSTC src/lib.rs -Z treat-err-as-bug=1 1>$TMPDIR/rust-test-disabled.log 2>&1 -should_be_empty_tmp=$(ls -l $TMPDIR/rustc-ice-*.txt 2>/dev/null | wc -l) -should_be_empty_dot=$(ls -l ./rustc-ice-*.txt 2>/dev/null | wc -l) - -echo "#### ICE Dump content:" -echo $content -echo "#### default length:" -echo $default -echo "#### short length:" -echo $short -echo "#### default_set length:" -echo $default_set -echo "#### full length:" -echo $full -echo "#### should_be_empty_dot length:" -echo $should_be_empty_dot -echo "#### should_be_empty_tmp length:" -echo $should_be_empty_tmp - -## Verify that a the ICE dump file is created in the appropriate directories, that -## their lengths are the same regardless of other backtrace configuration options, -## that the file is not created when asked to (RUSTC_ICE=0) and that the file -## contains at least part of the expected content. -if [ $short -eq $default_set ] && - #[ $default -eq $short ] && - [ $default_set -eq $full ] && - [[ $content == *"thread 'rustc' panicked at "* ]] && - [[ $content == *"stack backtrace:"* ]] && - #[ $default -gt 0 ] && - [ $should_be_empty_dot -eq 0 ] && - [ $should_be_empty_tmp -eq 0 ]; then - exit 0 -else - exit 1 -fi diff --git a/tests/run-make/dump-ice-to-disk/src/lib.rs b/tests/run-make/dump-ice-to-disk/lib.rs index b23b7f830d7..b23b7f830d7 100644 --- a/tests/run-make/dump-ice-to-disk/src/lib.rs +++ b/tests/run-make/dump-ice-to-disk/lib.rs diff --git a/tests/run-make/dump-ice-to-disk/rmake.rs b/tests/run-make/dump-ice-to-disk/rmake.rs new file mode 100644 index 00000000000..2fb5c825064 --- /dev/null +++ b/tests/run-make/dump-ice-to-disk/rmake.rs @@ -0,0 +1,81 @@ +// This test checks if internal compilation error (ICE) log files work as expected. +// - Get the number of lines from the log files without any configuration options, +// then check that the line count doesn't change if the backtrace gets configured to be short +// or full. +// - Check that disabling ICE logging results in zero files created. +// - Check that the ICE files contain some of the expected strings. +// See https://github.com/rust-lang/rust/pull/108714 + +use run_make_support::{cwd, has_extension, has_prefix, rfs, rustc, shallow_find_files}; + +fn main() { + rustc().input("lib.rs").arg("-Ztreat-err-as-bug=1").run_fail(); + let default = get_text_from_ice(".").lines().count(); + clear_ice_files(); + + rustc().env("RUSTC_ICE", cwd()).input("lib.rs").arg("-Ztreat-err-as-bug=1").run_fail(); + let ice_text = get_text_from_ice(cwd()); + let default_set = ice_text.lines().count(); + let content = ice_text; + let ice_files = shallow_find_files(cwd(), |path| { + has_prefix(path, "rustc-ice") && has_extension(path, "txt") + }); + assert_eq!(ice_files.len(), 1); // There should only be 1 ICE file. + let ice_file_name = + ice_files.first().and_then(|f| f.file_name()).and_then(|n| n.to_str()).unwrap(); + // Ensure that the ICE dump path doesn't contain `:`, because they cause problems on Windows. + assert!(!ice_file_name.contains(":"), "{ice_file_name}"); + + clear_ice_files(); + rustc() + .env("RUSTC_ICE", cwd()) + .input("lib.rs") + .env("RUST_BACKTRACE", "short") + .arg("-Ztreat-err-as-bug=1") + .run_fail(); + let short = get_text_from_ice(cwd()).lines().count(); + clear_ice_files(); + rustc() + .env("RUSTC_ICE", cwd()) + .input("lib.rs") + .env("RUST_BACKTRACE", "full") + .arg("-Ztreat-err-as-bug=1") + .run_fail(); + let full = get_text_from_ice(cwd()).lines().count(); + clear_ice_files(); + + // The ICE dump is explicitly disabled. Therefore, this should produce no files. + rustc().env("RUSTC_ICE", "0").input("lib.rs").arg("-Ztreat-err-as-bug=1").run_fail(); + let ice_files = shallow_find_files(cwd(), |path| { + has_prefix(path, "rustc-ice") && has_extension(path, "txt") + }); + assert!(ice_files.is_empty()); // There should be 0 ICE files. + + // The line count should not change. + assert_eq!(short, default_set); + assert_eq!(short, default); + assert_eq!(full, default_set); + assert!(default > 0); + // Some of the expected strings in an ICE file should appear. + assert!(content.contains("thread 'rustc' panicked at")); + assert!(content.contains("stack backtrace:")); +} + +fn clear_ice_files() { + let ice_files = shallow_find_files(cwd(), |path| { + has_prefix(path, "rustc-ice") && has_extension(path, "txt") + }); + for file in ice_files { + rfs::remove_file(file); + } +} + +#[track_caller] +fn get_text_from_ice(dir: impl AsRef<std::path::Path>) -> String { + let ice_files = + shallow_find_files(dir, |path| has_prefix(path, "rustc-ice") && has_extension(path, "txt")); + assert_eq!(ice_files.len(), 1); // There should only be 1 ICE file. + let ice_file = ice_files.get(0).unwrap(); + let output = rfs::read_to_string(ice_file); + output +} diff --git a/tests/run-make/export-executable-symbols/Makefile b/tests/run-make/export-executable-symbols/Makefile deleted file mode 100644 index c4d29aa2bf4..00000000000 --- a/tests/run-make/export-executable-symbols/Makefile +++ /dev/null @@ -1,11 +0,0 @@ -include ../tools.mk - -# ignore-wasm32 -# ignore-wasm64 -# ignore-none no-std is not supported -# only-linux - -all: - $(RUSTC) -Zexport-executable-symbols main.rs --target $(TARGET) --crate-type=bin - nm $(TMPDIR)/main | $(CGREP) exported_symbol - diff --git a/tests/run-make/export-executable-symbols/rmake.rs b/tests/run-make/export-executable-symbols/rmake.rs new file mode 100644 index 00000000000..77f968189b6 --- /dev/null +++ b/tests/run-make/export-executable-symbols/rmake.rs @@ -0,0 +1,25 @@ +// The unstable flag `-Z export-executable-symbols` exports symbols from executables, as if +// they were dynamic libraries. This test is a simple smoke test to check that this feature +// works by using it in compilation, then checking that the output binary contains the exported +// symbol. +// See https://github.com/rust-lang/rust/pull/85673 + +//@ only-unix +// Reason: the export-executable-symbols flag only works on Unix +// due to hardcoded platform-specific implementation +// (See #85673) +//@ ignore-wasm32 +//@ ignore-wasm64 +//@ ignore-none +// Reason: no-std is not supported + +use run_make_support::{bin_name, llvm_readobj, rustc}; + +fn main() { + rustc().arg("-Zexport-executable-symbols").input("main.rs").crate_type("bin").run(); + llvm_readobj() + .symbols() + .input(bin_name("main")) + .run() + .assert_stdout_contains("exported_symbol"); +} diff --git a/tests/run-make/extern-flag-disambiguates/Makefile b/tests/run-make/extern-flag-disambiguates/Makefile deleted file mode 100644 index e54a537ecd0..00000000000 --- a/tests/run-make/extern-flag-disambiguates/Makefile +++ /dev/null @@ -1,26 +0,0 @@ -# ignore-cross-compile -include ../tools.mk - -# Attempt to build this dependency tree: -# -# A.1 A.2 -# |\ | -# | \ | -# B \ C -# \ | / -# \|/ -# D -# -# Note that A.1 and A.2 are crates with the same name. - -all: - $(RUSTC) -C metadata=1 -C extra-filename=-1 a.rs - $(RUSTC) -C metadata=2 -C extra-filename=-2 a.rs - $(RUSTC) b.rs --extern a=$(TMPDIR)/liba-1.rlib - $(RUSTC) c.rs --extern a=$(TMPDIR)/liba-2.rlib - @echo before - $(RUSTC) --cfg before d.rs --extern a=$(TMPDIR)/liba-1.rlib - $(call RUN,d) - @echo after - $(RUSTC) --cfg after d.rs --extern a=$(TMPDIR)/liba-1.rlib - $(call RUN,d) diff --git a/tests/run-make/extern-flag-disambiguates/rmake.rs b/tests/run-make/extern-flag-disambiguates/rmake.rs new file mode 100644 index 00000000000..2d7d7f69f66 --- /dev/null +++ b/tests/run-make/extern-flag-disambiguates/rmake.rs @@ -0,0 +1,30 @@ +//@ ignore-cross-compile + +use run_make_support::{cwd, run, rustc}; + +// Attempt to build this dependency tree: +// +// A.1 A.2 +// |\ | +// | \ | +// B \ C +// \ | / +// \|/ +// D +// +// Note that A.1 and A.2 are crates with the same name. + +// original Makefile at https://github.com/rust-lang/rust/issues/14469 + +fn main() { + rustc().metadata("1").extra_filename("-1").input("a.rs").run(); + rustc().metadata("2").extra_filename("-2").input("a.rs").run(); + rustc().input("b.rs").extern_("a", "liba-1.rlib").run(); + rustc().input("c.rs").extern_("a", "liba-2.rlib").run(); + println!("before"); + rustc().cfg("before").input("d.rs").extern_("a", "liba-1.rlib").run(); + run("d"); + println!("after"); + rustc().cfg("after").input("d.rs").extern_("a", "liba-1.rlib").run(); + run("d"); +} diff --git a/tests/run-make/foreign-rust-exceptions/Makefile b/tests/run-make/foreign-rust-exceptions/Makefile deleted file mode 100644 index 59cee284200..00000000000 --- a/tests/run-make/foreign-rust-exceptions/Makefile +++ /dev/null @@ -1,13 +0,0 @@ -# ignore-cross-compile -# ignore-i686-pc-windows-gnu -# needs-unwind - -# This test doesn't work on 32-bit MinGW as cdylib has its own copy of unwinder -# so cross-DLL unwinding does not work. - -include ../tools.mk - -all: - $(RUSTC) bar.rs --crate-type=cdylib - $(RUSTC) foo.rs - $(call RUN,foo) 2>&1 | $(CGREP) "Rust cannot catch foreign exceptions" diff --git a/tests/run-make/foreign-rust-exceptions/rmake.rs b/tests/run-make/foreign-rust-exceptions/rmake.rs new file mode 100644 index 00000000000..9c917078aaa --- /dev/null +++ b/tests/run-make/foreign-rust-exceptions/rmake.rs @@ -0,0 +1,23 @@ +// Rust exceptions can be foreign (from C code, in this test) or local. Foreign +// exceptions should not be caught, as that can cause undefined behaviour. Instead +// of catching them, #102721 made it so that the binary panics in execution with a helpful message. +// This test checks that the correct message appears and that execution fails when trying to catch +// a foreign exception. +// See https://github.com/rust-lang/rust/issues/102715 + +//@ ignore-cross-compile +// Reason: the compiled binary is executed +//@ needs-unwind +// Reason: unwinding panics is exercised in this test + +//@ ignore-i686-pc-windows-gnu +// Reason: This test doesn't work on 32-bit MinGW as cdylib has its own copy of unwinder +// so cross-DLL unwinding does not work. + +use run_make_support::{run_fail, rustc}; + +fn main() { + rustc().input("bar.rs").crate_type("cdylib").run(); + rustc().input("foo.rs").run(); + run_fail("foo").assert_stderr_contains("Rust cannot catch foreign exceptions"); +} diff --git a/tests/run-make/incr-foreign-head-span/Makefile b/tests/run-make/incr-foreign-head-span/Makefile deleted file mode 100644 index 9be4b0f601c..00000000000 --- a/tests/run-make/incr-foreign-head-span/Makefile +++ /dev/null @@ -1,21 +0,0 @@ -include ../tools.mk - -# ignore-none no-std is not supported -# ignore-nvptx64-nvidia-cuda FIXME: can't find crate for 'std' - -# Ensure that modifying a crate on disk (without recompiling it) -# does not cause ICEs in downstream crates. -# Previously, we would call `SourceMap.guess_head_span` on a span -# from an external crate, which would cause us to read an upstream -# source file from disk during compilation of a downstream crate -# See #86480 for more details - -INCR=$(TMPDIR)/incr - -all: - cp first_crate.rs second_crate.rs $(TMPDIR) - $(RUSTC) $(TMPDIR)/first_crate.rs -C incremental=$(INCR) --target $(TARGET) --crate-type lib - $(RUSTC) $(TMPDIR)/second_crate.rs -C incremental=$(INCR) --target $(TARGET) --extern first_crate=$(TMPDIR)/libfirst_crate.rlib --crate-type lib - rm $(TMPDIR)/first_crate.rs - $(RUSTC) $(TMPDIR)/second_crate.rs -C incremental=$(INCR) --target $(TARGET) --cfg second_run --crate-type lib - diff --git a/tests/run-make/incr-foreign-head-span/rmake.rs b/tests/run-make/incr-foreign-head-span/rmake.rs new file mode 100644 index 00000000000..92e2ed5f879 --- /dev/null +++ b/tests/run-make/incr-foreign-head-span/rmake.rs @@ -0,0 +1,25 @@ +// Ensure that modifying a crate on disk (without recompiling it) +// does not cause ICEs (internal compiler errors) in downstream crates. +// Previously, we would call `SourceMap.guess_head_span` on a span +// from an external crate, which would cause us to read an upstream +// source file from disk during compilation of a downstream crate. +// See https://github.com/rust-lang/rust/issues/86480 + +//@ ignore-none +// Reason: no-std is not supported +//@ ignore-nvptx64-nvidia-cuda +// Reason: can't find crate for 'std' + +use run_make_support::{rfs, rust_lib_name, rustc}; + +fn main() { + rustc().input("first_crate.rs").incremental("incr").crate_type("lib").run(); + rustc() + .input("second_crate.rs") + .incremental("incr") + .extern_("first_crate", rust_lib_name("first_crate")) + .crate_type("lib") + .run(); + rfs::remove_file("first_crate.rs"); + rustc().input("second_crate.rs").incremental("incr").cfg("second_run").crate_type("lib").run(); +} diff --git a/tests/run-make/interdependent-c-libraries/Makefile b/tests/run-make/interdependent-c-libraries/Makefile deleted file mode 100644 index 53a696d82bf..00000000000 --- a/tests/run-make/interdependent-c-libraries/Makefile +++ /dev/null @@ -1,15 +0,0 @@ -# ignore-cross-compile -include ../tools.mk - -# The rust crate foo will link to the native library foo, while the rust crate -# bar will link to the native library bar. There is also a dependency between -# the native library bar to the natibe library foo. -# -# This test ensures that the ordering of -lfoo and -lbar on the command line is -# correct to complete the linkage. If passed as "-lfoo -lbar", then the 'foo' -# library will be stripped out, and the linkage will fail. - -all: $(call NATIVE_STATICLIB,foo) $(call NATIVE_STATICLIB,bar) - $(RUSTC) foo.rs - $(RUSTC) bar.rs - $(RUSTC) main.rs --print link-args diff --git a/tests/run-make/interdependent-c-libraries/rmake.rs b/tests/run-make/interdependent-c-libraries/rmake.rs new file mode 100644 index 00000000000..ee8cc76c9cc --- /dev/null +++ b/tests/run-make/interdependent-c-libraries/rmake.rs @@ -0,0 +1,21 @@ +// The rust crate foo will link to the native library foo, while the rust crate +// bar will link to the native library bar. There is also a dependency between +// the native library bar to the natibe library foo. +// This test ensures that the ordering of -lfoo and -lbar on the command line is +// correct to complete the linkage. If passed as "-lfoo -lbar", then the 'foo' +// library will be stripped out, and the linkage will fail. +// See https://github.com/rust-lang/rust/commit/e6072fa0c4c22d62acf3dcb78c8ee260a1368bd7 + +//@ ignore-cross-compile +// Reason: linkage still fails as the object files produced are not in the correct +// format in the `build_native_static_lib` step + +use run_make_support::{build_native_static_lib, rustc}; + +fn main() { + build_native_static_lib("foo"); + build_native_static_lib("bar"); + rustc().input("foo.rs").run(); + rustc().input("bar.rs").run(); + rustc().input("main.rs").print("link-args").run(); +} diff --git a/tests/run-make/panic-abort-eh_frame/Makefile b/tests/run-make/panic-abort-eh_frame/Makefile deleted file mode 100644 index 7020455b742..00000000000 --- a/tests/run-make/panic-abort-eh_frame/Makefile +++ /dev/null @@ -1,10 +0,0 @@ -# only-linux -# -# This test ensures that `panic=abort` code (without `C-unwind`, that is) should not have any -# unwinding related `.eh_frame` sections emitted. - -include ../tools.mk - -all: - $(RUSTC) foo.rs --crate-type=lib --emit=obj=$(TMPDIR)/foo.o -Cpanic=abort --edition 2021 -Z validate-mir - objdump --dwarf=frames $(TMPDIR)/foo.o | $(CGREP) -v 'DW_CFA' diff --git a/tests/run-make/panic-abort-eh_frame/rmake.rs b/tests/run-make/panic-abort-eh_frame/rmake.rs new file mode 100644 index 00000000000..23d95dc5774 --- /dev/null +++ b/tests/run-make/panic-abort-eh_frame/rmake.rs @@ -0,0 +1,24 @@ +// An `.eh_frame` section in an object file is a symptom of an UnwindAction::Terminate +// being inserted, useful for determining whether or not unwinding is necessary. +// This is useless when panics would NEVER unwind due to -C panic=abort. This section should +// therefore never appear in the emit file of a -C panic=abort compilation, and this test +// checks that this is respected. +// See https://github.com/rust-lang/rust/pull/112403 + +//@ only-linux +// FIXME(Oneirical): the DW_CFA symbol appears on Windows-gnu, because uwtable +// is forced to true on Windows targets (see #128136). + +use run_make_support::{llvm_objdump, rustc}; + +fn main() { + rustc() + .input("foo.rs") + .crate_type("lib") + .emit("obj=foo.o") + .panic("abort") + .edition("2021") + .arg("-Zvalidate-mir") + .run(); + llvm_objdump().arg("--dwarf=frames").input("foo.o").run().assert_stdout_not_contains("DW_CFA"); +} diff --git a/tests/run-make/sanitizer-cdylib-link/Makefile b/tests/run-make/sanitizer-cdylib-link/Makefile deleted file mode 100644 index 10d94afc39e..00000000000 --- a/tests/run-make/sanitizer-cdylib-link/Makefile +++ /dev/null @@ -1,16 +0,0 @@ -# needs-sanitizer-support -# needs-sanitizer-address - -include ../tools.mk - -LOG := $(TMPDIR)/log.txt - -# This test builds a shared object, then an executable that links it as a native -# rust library (contrast to an rlib). The shared library and executable both -# are compiled with address sanitizer, and we assert that a fault in the cdylib -# is correctly detected. - -all: - $(RUSTC) -g -Z sanitizer=address --crate-type cdylib --target $(TARGET) library.rs - $(RUSTC) -g -Z sanitizer=address --crate-type bin --target $(TARGET) program.rs - LD_LIBRARY_PATH=$(TMPDIR) $(TMPDIR)/program 2>&1 | $(CGREP) stack-buffer-overflow diff --git a/tests/run-make/sanitizer-cdylib-link/rmake.rs b/tests/run-make/sanitizer-cdylib-link/rmake.rs new file mode 100644 index 00000000000..f9d7fd98789 --- /dev/null +++ b/tests/run-make/sanitizer-cdylib-link/rmake.rs @@ -0,0 +1,17 @@ +// Identical to sanitizer-dylib-link, but with a cdylib. +// This test builds a shared object, then an executable that links it as a native +// rust library (contrast to an rlib). The shared library and executable both +// are compiled with address sanitizer, and we assert that a fault in the cdylib +// is correctly detected. +// See https://github.com/rust-lang/rust/pull/38699 + +//@ needs-sanitizer-support +//@ needs-sanitizer-address + +use run_make_support::{run_fail, rustc}; + +fn main() { + rustc().arg("-g").arg("-Zsanitizer=address").crate_type("cdylib").input("library.rs").run(); + rustc().arg("-g").arg("-Zsanitizer=address").crate_type("bin").input("program.rs").run(); + run_fail("program").assert_stderr_contains("stack-buffer-overflow"); +} diff --git a/tests/run-make/sanitizer-dylib-link/Makefile b/tests/run-make/sanitizer-dylib-link/Makefile deleted file mode 100644 index c5a698db3a0..00000000000 --- a/tests/run-make/sanitizer-dylib-link/Makefile +++ /dev/null @@ -1,16 +0,0 @@ -# needs-sanitizer-support -# needs-sanitizer-address - -include ../tools.mk - -LOG := $(TMPDIR)/log.txt - -# This test builds a shared object, then an executable that links it as a native -# rust library (contrast to an rlib). The shared library and executable both -# are compiled with address sanitizer, and we assert that a fault in the dylib -# is correctly detected. - -all: - $(RUSTC) -g -Z sanitizer=address --crate-type dylib --target $(TARGET) library.rs - $(RUSTC) -g -Z sanitizer=address --crate-type bin --target $(TARGET) program.rs - LD_LIBRARY_PATH=$(TMPDIR) $(TMPDIR)/program 2>&1 | $(CGREP) stack-buffer-overflow diff --git a/tests/run-make/sanitizer-dylib-link/rmake.rs b/tests/run-make/sanitizer-dylib-link/rmake.rs new file mode 100644 index 00000000000..b43420adc72 --- /dev/null +++ b/tests/run-make/sanitizer-dylib-link/rmake.rs @@ -0,0 +1,16 @@ +// This test builds a shared object, then an executable that links it as a native +// rust library (contrast to an rlib). The shared library and executable both +// are compiled with address sanitizer, and we assert that a fault in the dylib +// is correctly detected. +// See https://github.com/rust-lang/rust/pull/38699 + +//@ needs-sanitizer-support +//@ needs-sanitizer-address + +use run_make_support::{run_fail, rustc}; + +fn main() { + rustc().arg("-g").arg("-Zsanitizer=address").crate_type("dylib").input("library.rs").run(); + rustc().arg("-g").arg("-Zsanitizer=address").crate_type("bin").input("program.rs").run(); + run_fail("program").assert_stderr_contains("stack-buffer-overflow"); +} diff --git a/tests/run-make/sanitizer-staticlib-link/Makefile b/tests/run-make/sanitizer-staticlib-link/Makefile deleted file mode 100644 index 7b1a286ed12..00000000000 --- a/tests/run-make/sanitizer-staticlib-link/Makefile +++ /dev/null @@ -1,20 +0,0 @@ -# needs-sanitizer-support -# needs-sanitizer-address - -include ../tools.mk - -# This test first builds a staticlib with AddressSanitizer and checks that -# linking it to an executable fails due to the missing sanitizer runtime. -# It then builds an executable linking to the staticlib and checks that -# the fault in the staticlib is detected correctly. - -# Note that checking for the link failure actually checks two things at once: -# 1) That the library has the sanitizer intrumentation -# 2) and that library does not have the sanitizer runtime - -all: - $(RUSTC) -g -Z sanitizer=address --crate-type staticlib --target $(TARGET) library.rs - ! $(CC) program.c $(call STATICLIB,library) $(call OUT_EXE,program) $(EXTRACFLAGS) $(EXTRACXXFLAGS) - $(RUSTC) -g -Z sanitizer=address --crate-type bin --target $(TARGET) -L . program.rs - LD_LIBRARY_PATH=$(TMPDIR) $(TMPDIR)/program 2>&1 | $(CGREP) stack-buffer-overflow - diff --git a/tests/run-make/sanitizer-staticlib-link/rmake.rs b/tests/run-make/sanitizer-staticlib-link/rmake.rs new file mode 100644 index 00000000000..e38d15a8a3c --- /dev/null +++ b/tests/run-make/sanitizer-staticlib-link/rmake.rs @@ -0,0 +1,26 @@ +// This test first builds a staticlib with AddressSanitizer and checks that +// linking it to an executable fails due to the missing sanitizer runtime. +// It then builds an executable linking to the staticlib and checks that +// the fault in the staticlib is detected correctly. + +// Note that checking for the link failure actually checks two things at once: +// 1) That the library has the sanitizer intrumentation +// 2) and that library does not have the sanitizer runtime +// See https://github.com/rust-lang/rust/pull/38699 + +//@ needs-sanitizer-support +//@ needs-sanitizer-address + +use run_make_support::{cc, extra_c_flags, extra_cxx_flags, run_fail, rustc, static_lib_name}; + +fn main() { + rustc().arg("-g").arg("-Zsanitizer=address").crate_type("staticlib").input("library.rs").run(); + cc().input("program.c") + .arg(static_lib_name("library")) + .out_exe("program") + .args(extra_c_flags()) + .args(extra_cxx_flags()) + .run_fail(); + rustc().arg("-g").arg("-Zsanitizer=address").crate_type("bin").input("program.rs").run(); + run_fail("program").assert_stderr_contains("stack-buffer-overflow"); +} diff --git a/tests/run-make/static-dylib-by-default/Makefile b/tests/run-make/static-dylib-by-default/Makefile deleted file mode 100644 index cdaab42d06c..00000000000 --- a/tests/run-make/static-dylib-by-default/Makefile +++ /dev/null @@ -1,17 +0,0 @@ -# ignore-cross-compile -include ../tools.mk - -TO_LINK := $(call DYLIB,bar) -ifdef IS_MSVC -LINK_ARG = $(TO_LINK:dll=dll.lib) -else -LINK_ARG = $(TO_LINK) -endif - -all: - $(RUSTC) foo.rs - $(RUSTC) bar.rs - $(CC) main.c $(call OUT_EXE,main) $(LINK_ARG) $(EXTRACFLAGS) - rm $(TMPDIR)/*.rlib - rm $(call DYLIB,foo) - $(call RUN,main) diff --git a/tests/run-make/static-dylib-by-default/rmake.rs b/tests/run-make/static-dylib-by-default/rmake.rs new file mode 100644 index 00000000000..133210c74e7 --- /dev/null +++ b/tests/run-make/static-dylib-by-default/rmake.rs @@ -0,0 +1,35 @@ +// If a dylib is being produced, the compiler will first check to see if it can +// be created entirely statically before falling back to dynamic dependencies. This +// behavior can be overridden with `-C prefer-dynamic`. +// In this test, bar depends on foo and is compiled fully statically despite the available +// `foo` dynamic library. This allows the main binary to be executed in the final step. +// See https://github.com/rust-lang/rust/commit/3036b001276a6e43409b08b7f2334ce72aeeb036 + +//@ ignore-cross-compile +// Reason: the compiled binary is executed + +use run_make_support::{ + cc, cwd, dynamic_lib_name, extra_c_flags, has_extension, is_msvc, rfs, run, rustc, + shallow_find_files, +}; + +fn main() { + rustc().input("foo.rs").run(); + rustc().input("bar.rs").run(); + // On msvc, dynamic libraries are compiled by rustc to: + // bar.dll // dylib + // bar.dll.lib // import library for the dylib + // bar.dll.exp // export library for the dylib + // msvc's underlying link.exe requires the import library for the dynamic library as input. + // That is why the library is bar.dll.lib, not bar.dll. + let library = if is_msvc() { "bar.dll.lib" } else { &dynamic_lib_name("bar") }; + cc().input("main.c").out_exe("main").arg(library).args(extra_c_flags()).run(); + for rlib in shallow_find_files(cwd(), |path| has_extension(path, "rlib")) { + rfs::remove_file(rlib); + } + rfs::remove_file(dynamic_lib_name("foo")); + if is_msvc() { + rfs::remove_file("foo.dll.lib"); + } + run("main"); +} diff --git a/tests/rustdoc-gui/copy-code.goml b/tests/rustdoc-gui/copy-code.goml new file mode 100644 index 00000000000..72a5bece175 --- /dev/null +++ b/tests/rustdoc-gui/copy-code.goml @@ -0,0 +1,54 @@ +// Checks that the "copy code" button is not triggering JS error and its display +// isn't broken. +go-to: "file://" + |DOC_PATH| + "/test_docs/fn.foo.html" + +define-function: ( + "check-copy-button", + [], + block { + // First we ensure that there are no "copy code" currently existing. + assert-count: (".example-wrap .copy-button", 0) + move-cursor-to: ".example-wrap" + assert-count: (".example-wrap .copy-button", 1) + // We now ensure it's only displayed when the example is hovered. + assert-css: (".example-wrap .copy-button", { "visibility": "visible" }) + move-cursor-to: ".search-input" + assert-css: (".example-wrap .copy-button", { "visibility": "hidden" }) + // Checking that the copy button has the same size as the "copy path" button. + compare-elements-size: ( + "#copy-path", + ".example-wrap:nth-of-type(1) .copy-button", + ["height", "width"], + ) + }, +) + +call-function: ("check-copy-button", {}) +// Checking that the run button and the copy button have the same height. +compare-elements-size: ( + ".example-wrap:nth-of-type(1) .test-arrow", + ".example-wrap:nth-of-type(1) .copy-button", + ["height"], +) +// ... and the same y position. +compare-elements-position: ( + ".example-wrap:nth-of-type(1) .test-arrow", + ".example-wrap:nth-of-type(1) .copy-button", + ["y"], +) +store-size: (".example-wrap:nth-of-type(1) .copy-button", { + "height": copy_height, + "width": copy_width, +}) +assert: |copy_height| > 0 && |copy_width| > 0 + +// Checking same things for the copy button when there is no run button. +go-to: "file://" + |DOC_PATH| + "/lib2/sub_mod/struct.Foo.html" +call-function: ("check-copy-button", {}) +// Ensure there is no run button. +assert-count: (".example-wrap .test-arrow", 0) +// Check it's the same size without a run button. +assert-size: (".example-wrap:nth-of-type(1) .copy-button", { + "height": |copy_height|, + "width": |copy_width|, +}) diff --git a/tests/rustdoc-gui/run-on-hover.goml b/tests/rustdoc-gui/run-on-hover.goml index 087dd3374f8..b62da79b780 100644 --- a/tests/rustdoc-gui/run-on-hover.goml +++ b/tests/rustdoc-gui/run-on-hover.goml @@ -17,16 +17,16 @@ define-function: ( "visibility": "visible", "color": |color|, "background-color": |background|, - "font-size": "22px", - "border-radius": "5px", + "font-size": "16px", + "border-radius": "2px", }) move-cursor-to: ".test-arrow" assert-css: (".test-arrow:hover", { "visibility": "visible", "color": |hover_color|, "background-color": |hover_background|, - "font-size": "22px", - "border-radius": "5px", + "font-size": "16px", + "border-radius": "2px", }) }, ) diff --git a/tests/rustdoc-gui/search-title.goml b/tests/rustdoc-gui/search-title.goml new file mode 100644 index 00000000000..95bc36af449 --- /dev/null +++ b/tests/rustdoc-gui/search-title.goml @@ -0,0 +1,24 @@ +// Checks that the search changes the title +include: "utils.goml" +go-to: "file://" + |DOC_PATH| + "/test_docs/index.html" + +store-value: (title, "test_docs - Rust") +assert-document-property: {"title": |title|} + +write-into: (".search-input", "test") +// To be SURE that the search will be run. +press-key: 'Enter' +wait-for: "#crate-search" + +assert-document-property: {"title": '"test" Search - Rust'} + +set-property: (".search-input", {"value": "another one"}) +// To be SURE that the search will be run. +press-key: 'Enter' +wait-for: "#crate-search" + +assert-document-property: {"title": '"another one" Search - Rust'} + +press-key: "Escape" + +assert-document-property: {"title": |title|} diff --git a/tests/ui/array-slice-vec/slice_is_sorted_by_borrow.rs b/tests/ui/array-slice-vec/slice_is_sorted_by_borrow.rs index 31f59f8f724..6ac90953a05 100644 --- a/tests/ui/array-slice-vec/slice_is_sorted_by_borrow.rs +++ b/tests/ui/array-slice-vec/slice_is_sorted_by_borrow.rs @@ -1,8 +1,6 @@ //@ check-pass // regression test for https://github.com/rust-lang/rust/issues/53485#issuecomment-885393452 -#![feature(is_sorted)] - struct A { name: String, } diff --git a/tests/ui/asm/aarch64/bad-options.rs b/tests/ui/asm/aarch64/bad-options.rs index 33b77367a4f..9e721d55b2d 100644 --- a/tests/ui/asm/aarch64/bad-options.rs +++ b/tests/ui/asm/aarch64/bad-options.rs @@ -26,14 +26,14 @@ fn main() { } global_asm!("", options(nomem)); -//~^ ERROR expected one of +//~^ ERROR the `nomem` option cannot be used with `global_asm!` global_asm!("", options(readonly)); -//~^ ERROR expected one of +//~^ ERROR the `readonly` option cannot be used with `global_asm!` global_asm!("", options(noreturn)); -//~^ ERROR expected one of +//~^ ERROR the `noreturn` option cannot be used with `global_asm!` global_asm!("", options(pure)); -//~^ ERROR expected one of +//~^ ERROR the `pure` option cannot be used with `global_asm!` global_asm!("", options(nostack)); -//~^ ERROR expected one of +//~^ ERROR the `nostack` option cannot be used with `global_asm!` global_asm!("", options(preserves_flags)); -//~^ ERROR expected one of +//~^ ERROR the `preserves_flags` option cannot be used with `global_asm!` diff --git a/tests/ui/asm/aarch64/bad-options.stderr b/tests/ui/asm/aarch64/bad-options.stderr index 21bcc4a9c7b..54ab7cafa49 100644 --- a/tests/ui/asm/aarch64/bad-options.stderr +++ b/tests/ui/asm/aarch64/bad-options.stderr @@ -36,41 +36,41 @@ LL | asm!("{}", out(reg) foo, clobber_abi("C")); | | | generic outputs -error: expected one of `)`, `att_syntax`, or `raw`, found `nomem` +error: the `nomem` option cannot be used with `global_asm!` --> $DIR/bad-options.rs:28:25 | LL | global_asm!("", options(nomem)); - | ^^^^^ expected one of `)`, `att_syntax`, or `raw` + | ^^^^^ the `nomem` option is not meaningful for global-scoped inline assembly -error: expected one of `)`, `att_syntax`, or `raw`, found `readonly` +error: the `readonly` option cannot be used with `global_asm!` --> $DIR/bad-options.rs:30:25 | LL | global_asm!("", options(readonly)); - | ^^^^^^^^ expected one of `)`, `att_syntax`, or `raw` + | ^^^^^^^^ the `readonly` option is not meaningful for global-scoped inline assembly -error: expected one of `)`, `att_syntax`, or `raw`, found `noreturn` +error: the `noreturn` option cannot be used with `global_asm!` --> $DIR/bad-options.rs:32:25 | LL | global_asm!("", options(noreturn)); - | ^^^^^^^^ expected one of `)`, `att_syntax`, or `raw` + | ^^^^^^^^ the `noreturn` option is not meaningful for global-scoped inline assembly -error: expected one of `)`, `att_syntax`, or `raw`, found `pure` +error: the `pure` option cannot be used with `global_asm!` --> $DIR/bad-options.rs:34:25 | LL | global_asm!("", options(pure)); - | ^^^^ expected one of `)`, `att_syntax`, or `raw` + | ^^^^ the `pure` option is not meaningful for global-scoped inline assembly -error: expected one of `)`, `att_syntax`, or `raw`, found `nostack` +error: the `nostack` option cannot be used with `global_asm!` --> $DIR/bad-options.rs:36:25 | LL | global_asm!("", options(nostack)); - | ^^^^^^^ expected one of `)`, `att_syntax`, or `raw` + | ^^^^^^^ the `nostack` option is not meaningful for global-scoped inline assembly -error: expected one of `)`, `att_syntax`, or `raw`, found `preserves_flags` +error: the `preserves_flags` option cannot be used with `global_asm!` --> $DIR/bad-options.rs:38:25 | LL | global_asm!("", options(preserves_flags)); - | ^^^^^^^^^^^^^^^ expected one of `)`, `att_syntax`, or `raw` + | ^^^^^^^^^^^^^^^ the `preserves_flags` option is not meaningful for global-scoped inline assembly error: invalid ABI for `clobber_abi` --> $DIR/bad-options.rs:20:18 diff --git a/tests/ui/asm/aarch64/parse-error.rs b/tests/ui/asm/aarch64/parse-error.rs index fbb1e08df91..ac73bbf99c9 100644 --- a/tests/ui/asm/aarch64/parse-error.rs +++ b/tests/ui/asm/aarch64/parse-error.rs @@ -98,8 +98,10 @@ global_asm!("", options(FOO)); //~^ ERROR expected one of global_asm!("", options(nomem FOO)); //~^ ERROR expected one of +//~| ERROR the `nomem` option cannot be used with `global_asm!` global_asm!("", options(nomem, FOO)); //~^ ERROR expected one of +//~| ERROR the `nomem` option cannot be used with `global_asm!` global_asm!("{}", options(), const FOO); global_asm!("", clobber_abi(FOO)); //~^ ERROR expected string literal diff --git a/tests/ui/asm/aarch64/parse-error.stderr b/tests/ui/asm/aarch64/parse-error.stderr index d21a8ab1f85..e2c798c798e 100644 --- a/tests/ui/asm/aarch64/parse-error.stderr +++ b/tests/ui/asm/aarch64/parse-error.stderr @@ -218,56 +218,68 @@ error: expected one of `)`, `att_syntax`, or `raw`, found `FOO` LL | global_asm!("", options(FOO)); | ^^^ expected one of `)`, `att_syntax`, or `raw` -error: expected one of `)`, `att_syntax`, or `raw`, found `nomem` +error: the `nomem` option cannot be used with `global_asm!` --> $DIR/parse-error.rs:99:25 | LL | global_asm!("", options(nomem FOO)); - | ^^^^^ expected one of `)`, `att_syntax`, or `raw` + | ^^^^^ the `nomem` option is not meaningful for global-scoped inline assembly -error: expected one of `)`, `att_syntax`, or `raw`, found `nomem` - --> $DIR/parse-error.rs:101:25 +error: expected one of `)` or `,`, found `FOO` + --> $DIR/parse-error.rs:99:31 + | +LL | global_asm!("", options(nomem FOO)); + | ^^^ expected one of `)` or `,` + +error: the `nomem` option cannot be used with `global_asm!` + --> $DIR/parse-error.rs:102:25 + | +LL | global_asm!("", options(nomem, FOO)); + | ^^^^^ the `nomem` option is not meaningful for global-scoped inline assembly + +error: expected one of `)`, `att_syntax`, or `raw`, found `FOO` + --> $DIR/parse-error.rs:102:32 | LL | global_asm!("", options(nomem, FOO)); - | ^^^^^ expected one of `)`, `att_syntax`, or `raw` + | ^^^ expected one of `)`, `att_syntax`, or `raw` error: expected string literal - --> $DIR/parse-error.rs:104:29 + --> $DIR/parse-error.rs:106:29 | LL | global_asm!("", clobber_abi(FOO)); | ^^^ not a string literal error: expected one of `)` or `,`, found `FOO` - --> $DIR/parse-error.rs:106:33 + --> $DIR/parse-error.rs:108:33 | LL | global_asm!("", clobber_abi("C" FOO)); | ^^^ expected one of `)` or `,` error: expected string literal - --> $DIR/parse-error.rs:108:34 + --> $DIR/parse-error.rs:110:34 | LL | global_asm!("", clobber_abi("C", FOO)); | ^^^ not a string literal error: `clobber_abi` cannot be used with `global_asm!` - --> $DIR/parse-error.rs:110:19 + --> $DIR/parse-error.rs:112:19 | LL | global_asm!("{}", clobber_abi("C"), const FOO); | ^^^^^^^^^^^^^^^^ error: `clobber_abi` cannot be used with `global_asm!` - --> $DIR/parse-error.rs:112:28 + --> $DIR/parse-error.rs:114:28 | LL | global_asm!("", options(), clobber_abi("C")); | ^^^^^^^^^^^^^^^^ error: `clobber_abi` cannot be used with `global_asm!` - --> $DIR/parse-error.rs:114:30 + --> $DIR/parse-error.rs:116:30 | LL | global_asm!("{}", options(), clobber_abi("C"), const FOO); | ^^^^^^^^^^^^^^^^ error: duplicate argument named `a` - --> $DIR/parse-error.rs:116:35 + --> $DIR/parse-error.rs:118:35 | LL | global_asm!("{a}", a = const FOO, a = const BAR); | ------------- ^^^^^^^^^^^^^ duplicate argument @@ -275,7 +287,7 @@ LL | global_asm!("{a}", a = const FOO, a = const BAR); | previously here error: argument never used - --> $DIR/parse-error.rs:116:35 + --> $DIR/parse-error.rs:118:35 | LL | global_asm!("{a}", a = const FOO, a = const BAR); | ^^^^^^^^^^^^^ argument never used @@ -283,19 +295,19 @@ LL | global_asm!("{a}", a = const FOO, a = const BAR); = help: if this argument is intentionally unused, consider using it in an asm comment: `"/* {1} */"` error: expected one of `clobber_abi`, `const`, `options`, or `sym`, found `""` - --> $DIR/parse-error.rs:119:28 + --> $DIR/parse-error.rs:121:28 | LL | global_asm!("", options(), ""); | ^^ expected one of `clobber_abi`, `const`, `options`, or `sym` error: expected one of `clobber_abi`, `const`, `options`, or `sym`, found `"{}"` - --> $DIR/parse-error.rs:121:30 + --> $DIR/parse-error.rs:123:30 | LL | global_asm!("{}", const FOO, "{}", const FOO); | ^^^^ expected one of `clobber_abi`, `const`, `options`, or `sym` error: asm template must be a string literal - --> $DIR/parse-error.rs:123:13 + --> $DIR/parse-error.rs:125:13 | LL | global_asm!(format!("{{{}}}", 0), const FOO); | ^^^^^^^^^^^^^^^^^^^^ @@ -303,7 +315,7 @@ LL | global_asm!(format!("{{{}}}", 0), const FOO); = note: this error originates in the macro `format` (in Nightly builds, run with -Z macro-backtrace for more info) error: asm template must be a string literal - --> $DIR/parse-error.rs:125:20 + --> $DIR/parse-error.rs:127:20 | LL | global_asm!("{1}", format!("{{{}}}", 0), const FOO, const BAR); | ^^^^^^^^^^^^^^^^^^^^ @@ -398,6 +410,6 @@ help: consider using `const` instead of `let` LL | const bar: /* Type */ = 0; | ~~~~~ ++++++++++++ -error: aborting due to 57 previous errors +error: aborting due to 59 previous errors For more information about this error, try `rustc --explain E0435`. diff --git a/tests/ui/asm/naked-functions-inline.rs b/tests/ui/asm/naked-functions-inline.rs new file mode 100644 index 00000000000..cfb38f2e738 --- /dev/null +++ b/tests/ui/asm/naked-functions-inline.rs @@ -0,0 +1,38 @@ +//@ needs-asm-support +#![feature(naked_functions)] +#![crate_type = "lib"] + +use std::arch::asm; + +#[naked] +pub unsafe extern "C" fn inline_none() { + asm!("", options(noreturn)); +} + +#[naked] +#[inline] +//~^ ERROR [E0736] +pub unsafe extern "C" fn inline_hint() { + asm!("", options(noreturn)); +} + +#[naked] +#[inline(always)] +//~^ ERROR [E0736] +pub unsafe extern "C" fn inline_always() { + asm!("", options(noreturn)); +} + +#[naked] +#[inline(never)] +//~^ ERROR [E0736] +pub unsafe extern "C" fn inline_never() { + asm!("", options(noreturn)); +} + +#[naked] +#[cfg_attr(all(), inline(never))] +//~^ ERROR [E0736] +pub unsafe extern "C" fn conditional_inline_never() { + asm!("", options(noreturn)); +} diff --git a/tests/ui/asm/naked-functions-inline.stderr b/tests/ui/asm/naked-functions-inline.stderr new file mode 100644 index 00000000000..84a688f6f53 --- /dev/null +++ b/tests/ui/asm/naked-functions-inline.stderr @@ -0,0 +1,35 @@ +error[E0736]: attribute incompatible with `#[naked]` + --> $DIR/naked-functions-inline.rs:13:1 + | +LL | #[naked] + | -------- function marked with `#[naked]` here +LL | #[inline] + | ^^^^^^^^^ the `inline` attribute is incompatible with `#[naked]` + +error[E0736]: attribute incompatible with `#[naked]` + --> $DIR/naked-functions-inline.rs:20:1 + | +LL | #[naked] + | -------- function marked with `#[naked]` here +LL | #[inline(always)] + | ^^^^^^^^^^^^^^^^^ the `inline` attribute is incompatible with `#[naked]` + +error[E0736]: attribute incompatible with `#[naked]` + --> $DIR/naked-functions-inline.rs:27:1 + | +LL | #[naked] + | -------- function marked with `#[naked]` here +LL | #[inline(never)] + | ^^^^^^^^^^^^^^^^ the `inline` attribute is incompatible with `#[naked]` + +error[E0736]: attribute incompatible with `#[naked]` + --> $DIR/naked-functions-inline.rs:34:19 + | +LL | #[naked] + | -------- function marked with `#[naked]` here +LL | #[cfg_attr(all(), inline(never))] + | ^^^^^^^^^^^^^ the `inline` attribute is incompatible with `#[naked]` + +error: aborting due to 4 previous errors + +For more information about this error, try `rustc --explain E0736`. diff --git a/tests/ui/asm/naked-functions-instruction-set.rs b/tests/ui/asm/naked-functions-instruction-set.rs new file mode 100644 index 00000000000..b81b65cff74 --- /dev/null +++ b/tests/ui/asm/naked-functions-instruction-set.rs @@ -0,0 +1,30 @@ +//@ compile-flags: --target armv5te-unknown-linux-gnueabi +//@ needs-llvm-components: arm +//@ needs-asm-support +//@ build-pass + +#![crate_type = "lib"] +#![feature(no_core, lang_items, rustc_attrs, naked_functions)] +#![no_core] + +#[rustc_builtin_macro] +macro_rules! asm { + () => {}; +} + +#[lang = "sized"] +trait Sized {} + +#[no_mangle] +#[naked] +#[instruction_set(arm::t32)] +unsafe extern "C" fn test_thumb() { + asm!("bx lr", options(noreturn)); +} + +#[no_mangle] +#[naked] +#[instruction_set(arm::t32)] +unsafe extern "C" fn test_arm() { + asm!("bx lr", options(noreturn)); +} diff --git a/tests/ui/asm/naked-functions-testattrs.rs b/tests/ui/asm/naked-functions-testattrs.rs new file mode 100644 index 00000000000..12943ac0378 --- /dev/null +++ b/tests/ui/asm/naked-functions-testattrs.rs @@ -0,0 +1,39 @@ +//@ needs-asm-support +//@ compile-flags: --test + +#![allow(undefined_naked_function_abi)] +#![feature(naked_functions)] +#![feature(test)] +#![crate_type = "lib"] + +use std::arch::asm; + +#[test] +#[naked] +//~^ ERROR [E0736] +fn test_naked() { + unsafe { asm!("", options(noreturn)) }; +} + +#[should_panic] +#[test] +#[naked] +//~^ ERROR [E0736] +fn test_naked_should_panic() { + unsafe { asm!("", options(noreturn)) }; +} + +#[ignore] +#[test] +#[naked] +//~^ ERROR [E0736] +fn test_naked_ignore() { + unsafe { asm!("", options(noreturn)) }; +} + +#[bench] +#[naked] +//~^ ERROR [E0736] +fn bench_naked() { + unsafe { asm!("", options(noreturn)) }; +} diff --git a/tests/ui/asm/naked-functions-testattrs.stderr b/tests/ui/asm/naked-functions-testattrs.stderr new file mode 100644 index 00000000000..4dabe41964a --- /dev/null +++ b/tests/ui/asm/naked-functions-testattrs.stderr @@ -0,0 +1,35 @@ +error[E0736]: cannot use `#[naked]` with testing attributes + --> $DIR/naked-functions-testattrs.rs:12:1 + | +LL | #[test] + | ------- function marked with testing attribute here +LL | #[naked] + | ^^^^^^^^ `#[naked]` is incompatible with testing attributes + +error[E0736]: cannot use `#[naked]` with testing attributes + --> $DIR/naked-functions-testattrs.rs:20:1 + | +LL | #[test] + | ------- function marked with testing attribute here +LL | #[naked] + | ^^^^^^^^ `#[naked]` is incompatible with testing attributes + +error[E0736]: cannot use `#[naked]` with testing attributes + --> $DIR/naked-functions-testattrs.rs:28:1 + | +LL | #[test] + | ------- function marked with testing attribute here +LL | #[naked] + | ^^^^^^^^ `#[naked]` is incompatible with testing attributes + +error[E0736]: cannot use `#[naked]` with testing attributes + --> $DIR/naked-functions-testattrs.rs:35:1 + | +LL | #[bench] + | -------- function marked with testing attribute here +LL | #[naked] + | ^^^^^^^^ `#[naked]` is incompatible with testing attributes + +error: aborting due to 4 previous errors + +For more information about this error, try `rustc --explain E0736`. diff --git a/tests/ui/asm/naked-functions.rs b/tests/ui/asm/naked-functions.rs index 6b2d2aea238..6d335ac2def 100644 --- a/tests/ui/asm/naked-functions.rs +++ b/tests/ui/asm/naked-functions.rs @@ -3,7 +3,7 @@ //@ ignore-spirv #![feature(naked_functions)] -#![feature(asm_const, asm_unwind)] +#![feature(asm_const, asm_unwind, linkage)] #![crate_type = "lib"] use std::arch::asm; @@ -163,57 +163,89 @@ pub unsafe extern "C" fn valid_att_syntax() { } #[naked] -pub unsafe extern "C" fn inline_none() { - asm!("", options(noreturn)); +#[naked] +pub unsafe extern "C" fn allow_compile_error(a: u32) -> u32 { + compile_error!("this is a user specified error") + //~^ ERROR this is a user specified error } #[naked] -#[inline] -//~^ ERROR naked functions cannot be inlined -pub unsafe extern "C" fn inline_hint() { - asm!("", options(noreturn)); +pub unsafe extern "C" fn allow_compile_error_and_asm(a: u32) -> u32 { + compile_error!("this is a user specified error"); + //~^ ERROR this is a user specified error + asm!("", options(noreturn)) } #[naked] -#[inline(always)] -//~^ ERROR naked functions cannot be inlined -pub unsafe extern "C" fn inline_always() { - asm!("", options(noreturn)); +pub unsafe extern "C" fn invalid_asm_syntax(a: u32) -> u32 { + asm!(invalid_syntax) + //~^ ERROR asm template must be a string literal } +#[cfg(target_arch = "x86_64")] +#[cfg_attr(target_pointer_width = "64", no_mangle)] #[naked] -#[inline(never)] -//~^ ERROR naked functions cannot be inlined -pub unsafe extern "C" fn inline_never() { - asm!("", options(noreturn)); +pub unsafe extern "C" fn compatible_cfg_attributes() { + asm!("", options(noreturn, att_syntax)); } +#[allow(dead_code)] +#[warn(dead_code)] +#[deny(dead_code)] +#[forbid(dead_code)] #[naked] -#[inline] -//~^ ERROR naked functions cannot be inlined -#[inline(always)] -//~^ ERROR naked functions cannot be inlined -#[inline(never)] -//~^ ERROR naked functions cannot be inlined -pub unsafe extern "C" fn inline_all() { - asm!("", options(noreturn)); +pub unsafe extern "C" fn compatible_diagnostic_attributes() { + asm!("", options(noreturn, raw)); } +#[deprecated = "test"] #[naked] -pub unsafe extern "C" fn allow_compile_error(a: u32) -> u32 { - compile_error!("this is a user specified error") - //~^ ERROR this is a user specified error +pub unsafe extern "C" fn compatible_deprecated_attributes() { + asm!("", options(noreturn, raw)); } +#[cfg(target_arch = "x86_64")] +#[must_use] #[naked] -pub unsafe extern "C" fn allow_compile_error_and_asm(a: u32) -> u32 { - compile_error!("this is a user specified error"); - //~^ ERROR this is a user specified error - asm!("", options(noreturn)) +pub unsafe extern "C" fn compatible_must_use_attributes() -> u64 { + asm!( + " + mov rax, 42 + ret + ", + options(noreturn) + ) } +#[export_name = "exported_function_name"] +#[link_section = ".custom_section"] +#[no_mangle] #[naked] -pub unsafe extern "C" fn invalid_asm_syntax(a: u32) -> u32 { - asm!(invalid_syntax) - //~^ ERROR asm template must be a string literal +pub unsafe extern "C" fn compatible_ffi_attributes_1() { + asm!("", options(noreturn, raw)); +} + +#[cold] +#[naked] +pub unsafe extern "C" fn compatible_codegen_attributes() { + asm!("", options(noreturn, raw)); +} + +#[cfg(target_arch = "x86_64")] +#[target_feature(enable = "sse2")] +#[naked] +pub unsafe extern "C" fn compatible_target_feature() { + asm!("", options(noreturn)); +} + +#[doc = "foo bar baz"] +#[naked] +pub unsafe extern "C" fn compatible_doc_attributes() { + asm!("", options(noreturn, raw)); +} + +#[linkage = "external"] +#[naked] +pub unsafe extern "C" fn compatible_linkage() { + asm!("", options(noreturn, raw)); } diff --git a/tests/ui/asm/naked-functions.stderr b/tests/ui/asm/naked-functions.stderr index 4dd9e29bdc6..93c02e2fbef 100644 --- a/tests/ui/asm/naked-functions.stderr +++ b/tests/ui/asm/naked-functions.stderr @@ -5,19 +5,19 @@ LL | asm!("", options(readonly, nostack), options(pure)); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^ error: this is a user specified error - --> $DIR/naked-functions.rs:204:5 + --> $DIR/naked-functions.rs:168:5 | LL | compile_error!("this is a user specified error") | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: this is a user specified error - --> $DIR/naked-functions.rs:210:5 + --> $DIR/naked-functions.rs:174:5 | LL | compile_error!("this is a user specified error"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: asm template must be a string literal - --> $DIR/naked-functions.rs:217:10 + --> $DIR/naked-functions.rs:181:10 | LL | asm!(invalid_syntax) | ^^^^^^^^^^^^^^ @@ -249,42 +249,6 @@ warning: Rust ABI is unsupported in naked functions LL | pub unsafe fn rust_abi() { | ^^^^^^^^^^^^^^^^^^^^^^^^ -error: naked functions cannot be inlined - --> $DIR/naked-functions.rs:171:1 - | -LL | #[inline] - | ^^^^^^^^^ - -error: naked functions cannot be inlined - --> $DIR/naked-functions.rs:178:1 - | -LL | #[inline(always)] - | ^^^^^^^^^^^^^^^^^ - -error: naked functions cannot be inlined - --> $DIR/naked-functions.rs:185:1 - | -LL | #[inline(never)] - | ^^^^^^^^^^^^^^^^ - -error: naked functions cannot be inlined - --> $DIR/naked-functions.rs:192:1 - | -LL | #[inline] - | ^^^^^^^^^ - -error: naked functions cannot be inlined - --> $DIR/naked-functions.rs:194:1 - | -LL | #[inline(always)] - | ^^^^^^^^^^^^^^^^^ - -error: naked functions cannot be inlined - --> $DIR/naked-functions.rs:196:1 - | -LL | #[inline(never)] - | ^^^^^^^^^^^^^^^^ - -error: aborting due to 33 previous errors; 2 warnings emitted +error: aborting due to 27 previous errors; 2 warnings emitted For more information about this error, try `rustc --explain E0787`. diff --git a/tests/ui/asm/parse-error.rs b/tests/ui/asm/parse-error.rs index a0251c6763b..9dec3a1c394 100644 --- a/tests/ui/asm/parse-error.rs +++ b/tests/ui/asm/parse-error.rs @@ -111,11 +111,15 @@ global_asm!("{}", const); global_asm!("{}", const(reg) FOO); //~^ ERROR expected one of global_asm!("", options(FOO)); -//~^ ERROR expected one of +//~^ ERROR expected one of `)`, `att_syntax`, or `raw`, found `FOO` +global_asm!("", options(FOO,)); +//~^ ERROR expected one of `)`, `att_syntax`, or `raw`, found `FOO` global_asm!("", options(nomem FOO)); -//~^ ERROR expected one of +//~^ ERROR the `nomem` option cannot be used with `global_asm!` +//~| ERROR expected one of `)` or `,`, found `FOO` global_asm!("", options(nomem, FOO)); -//~^ ERROR expected one of +//~^ ERROR the `nomem` option cannot be used with `global_asm!` +//~| ERROR expected one of `)`, `att_syntax`, or `raw`, found `FOO` global_asm!("{}", options(), const FOO); global_asm!("", clobber_abi(FOO)); //~^ ERROR expected string literal diff --git a/tests/ui/asm/parse-error.stderr b/tests/ui/asm/parse-error.stderr index 1999cd09aa3..e9ecd712bc3 100644 --- a/tests/ui/asm/parse-error.stderr +++ b/tests/ui/asm/parse-error.stderr @@ -264,62 +264,80 @@ error: expected one of `)`, `att_syntax`, or `raw`, found `FOO` LL | global_asm!("", options(FOO)); | ^^^ expected one of `)`, `att_syntax`, or `raw` -error: expected one of `)`, `att_syntax`, or `raw`, found `nomem` +error: expected one of `)`, `att_syntax`, or `raw`, found `FOO` --> $DIR/parse-error.rs:115:25 | -LL | global_asm!("", options(nomem FOO)); - | ^^^^^ expected one of `)`, `att_syntax`, or `raw` +LL | global_asm!("", options(FOO,)); + | ^^^ expected one of `)`, `att_syntax`, or `raw` -error: expected one of `)`, `att_syntax`, or `raw`, found `nomem` +error: the `nomem` option cannot be used with `global_asm!` --> $DIR/parse-error.rs:117:25 | +LL | global_asm!("", options(nomem FOO)); + | ^^^^^ the `nomem` option is not meaningful for global-scoped inline assembly + +error: expected one of `)` or `,`, found `FOO` + --> $DIR/parse-error.rs:117:31 + | +LL | global_asm!("", options(nomem FOO)); + | ^^^ expected one of `)` or `,` + +error: the `nomem` option cannot be used with `global_asm!` + --> $DIR/parse-error.rs:120:25 + | +LL | global_asm!("", options(nomem, FOO)); + | ^^^^^ the `nomem` option is not meaningful for global-scoped inline assembly + +error: expected one of `)`, `att_syntax`, or `raw`, found `FOO` + --> $DIR/parse-error.rs:120:32 + | LL | global_asm!("", options(nomem, FOO)); - | ^^^^^ expected one of `)`, `att_syntax`, or `raw` + | ^^^ expected one of `)`, `att_syntax`, or `raw` error: expected string literal - --> $DIR/parse-error.rs:120:29 + --> $DIR/parse-error.rs:124:29 | LL | global_asm!("", clobber_abi(FOO)); | ^^^ not a string literal error: expected one of `)` or `,`, found `FOO` - --> $DIR/parse-error.rs:122:33 + --> $DIR/parse-error.rs:126:33 | LL | global_asm!("", clobber_abi("C" FOO)); | ^^^ expected one of `)` or `,` error: expected string literal - --> $DIR/parse-error.rs:124:34 + --> $DIR/parse-error.rs:128:34 | LL | global_asm!("", clobber_abi("C", FOO)); | ^^^ not a string literal error: `clobber_abi` cannot be used with `global_asm!` - --> $DIR/parse-error.rs:126:19 + --> $DIR/parse-error.rs:130:19 | LL | global_asm!("{}", clobber_abi("C"), const FOO); | ^^^^^^^^^^^^^^^^ error: `clobber_abi` cannot be used with `global_asm!` - --> $DIR/parse-error.rs:128:28 + --> $DIR/parse-error.rs:132:28 | LL | global_asm!("", options(), clobber_abi("C")); | ^^^^^^^^^^^^^^^^ error: `clobber_abi` cannot be used with `global_asm!` - --> $DIR/parse-error.rs:130:30 + --> $DIR/parse-error.rs:134:30 | LL | global_asm!("{}", options(), clobber_abi("C"), const FOO); | ^^^^^^^^^^^^^^^^ error: `clobber_abi` cannot be used with `global_asm!` - --> $DIR/parse-error.rs:132:17 + --> $DIR/parse-error.rs:136:17 | LL | global_asm!("", clobber_abi("C"), clobber_abi("C")); | ^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^ error: duplicate argument named `a` - --> $DIR/parse-error.rs:134:35 + --> $DIR/parse-error.rs:138:35 | LL | global_asm!("{a}", a = const FOO, a = const BAR); | ------------- ^^^^^^^^^^^^^ duplicate argument @@ -327,7 +345,7 @@ LL | global_asm!("{a}", a = const FOO, a = const BAR); | previously here error: argument never used - --> $DIR/parse-error.rs:134:35 + --> $DIR/parse-error.rs:138:35 | LL | global_asm!("{a}", a = const FOO, a = const BAR); | ^^^^^^^^^^^^^ argument never used @@ -335,19 +353,19 @@ LL | global_asm!("{a}", a = const FOO, a = const BAR); = help: if this argument is intentionally unused, consider using it in an asm comment: `"/* {1} */"` error: expected one of `clobber_abi`, `const`, `options`, or `sym`, found `""` - --> $DIR/parse-error.rs:137:28 + --> $DIR/parse-error.rs:141:28 | LL | global_asm!("", options(), ""); | ^^ expected one of `clobber_abi`, `const`, `options`, or `sym` error: expected one of `clobber_abi`, `const`, `options`, or `sym`, found `"{}"` - --> $DIR/parse-error.rs:139:30 + --> $DIR/parse-error.rs:143:30 | LL | global_asm!("{}", const FOO, "{}", const FOO); | ^^^^ expected one of `clobber_abi`, `const`, `options`, or `sym` error: asm template must be a string literal - --> $DIR/parse-error.rs:141:13 + --> $DIR/parse-error.rs:145:13 | LL | global_asm!(format!("{{{}}}", 0), const FOO); | ^^^^^^^^^^^^^^^^^^^^ @@ -355,7 +373,7 @@ LL | global_asm!(format!("{{{}}}", 0), const FOO); = note: this error originates in the macro `format` (in Nightly builds, run with -Z macro-backtrace for more info) error: asm template must be a string literal - --> $DIR/parse-error.rs:143:20 + --> $DIR/parse-error.rs:147:20 | LL | global_asm!("{1}", format!("{{{}}}", 0), const FOO, const BAR); | ^^^^^^^^^^^^^^^^^^^^ @@ -363,7 +381,7 @@ LL | global_asm!("{1}", format!("{{{}}}", 0), const FOO, const BAR); = note: this error originates in the macro `format` (in Nightly builds, run with -Z macro-backtrace for more info) error: expected operand, options, or additional template string - --> $DIR/parse-error.rs:145:19 + --> $DIR/parse-error.rs:149:19 | LL | global_asm!("{}", label {}); | ^^^^^^^^ expected operand, options, or additional template string @@ -423,6 +441,6 @@ help: consider using `const` instead of `let` LL | const bar: /* Type */ = 0; | ~~~~~ ++++++++++++ -error: aborting due to 64 previous errors +error: aborting due to 67 previous errors For more information about this error, try `rustc --explain E0435`. diff --git a/tests/ui/asm/unsupported-option.fixed b/tests/ui/asm/unsupported-option.fixed new file mode 100644 index 00000000000..d313d8028b6 --- /dev/null +++ b/tests/ui/asm/unsupported-option.fixed @@ -0,0 +1,11 @@ +//@ needs-asm-support +//@ run-rustfix + +use std::arch::global_asm; + +fn main() {} + +global_asm!("", options( raw)); +//~^ ERROR the `nomem` option cannot be used with `global_asm!` +//~| ERROR the `readonly` option cannot be used with `global_asm!` +//~| ERROR the `noreturn` option cannot be used with `global_asm!` diff --git a/tests/ui/asm/unsupported-option.rs b/tests/ui/asm/unsupported-option.rs new file mode 100644 index 00000000000..d75f8e7f569 --- /dev/null +++ b/tests/ui/asm/unsupported-option.rs @@ -0,0 +1,11 @@ +//@ needs-asm-support +//@ run-rustfix + +use std::arch::global_asm; + +fn main() {} + +global_asm!("", options(nomem, readonly, noreturn, raw)); +//~^ ERROR the `nomem` option cannot be used with `global_asm!` +//~| ERROR the `readonly` option cannot be used with `global_asm!` +//~| ERROR the `noreturn` option cannot be used with `global_asm!` diff --git a/tests/ui/asm/unsupported-option.stderr b/tests/ui/asm/unsupported-option.stderr new file mode 100644 index 00000000000..7a6927152b6 --- /dev/null +++ b/tests/ui/asm/unsupported-option.stderr @@ -0,0 +1,20 @@ +error: the `nomem` option cannot be used with `global_asm!` + --> $DIR/unsupported-option.rs:8:25 + | +LL | global_asm!("", options(nomem, readonly, noreturn, raw)); + | ^^^^^ the `nomem` option is not meaningful for global-scoped inline assembly + +error: the `readonly` option cannot be used with `global_asm!` + --> $DIR/unsupported-option.rs:8:32 + | +LL | global_asm!("", options(nomem, readonly, noreturn, raw)); + | ^^^^^^^^ the `readonly` option is not meaningful for global-scoped inline assembly + +error: the `noreturn` option cannot be used with `global_asm!` + --> $DIR/unsupported-option.rs:8:42 + | +LL | global_asm!("", options(nomem, readonly, noreturn, raw)); + | ^^^^^^^^ the `noreturn` option is not meaningful for global-scoped inline assembly + +error: aborting due to 3 previous errors + diff --git a/tests/ui/asm/x86_64/bad-options.rs b/tests/ui/asm/x86_64/bad-options.rs index f9cc13cfc5a..6424a1b1d42 100644 --- a/tests/ui/asm/x86_64/bad-options.rs +++ b/tests/ui/asm/x86_64/bad-options.rs @@ -33,14 +33,14 @@ fn main() { } global_asm!("", options(nomem)); -//~^ ERROR expected one of +//~^ ERROR the `nomem` option cannot be used with `global_asm!` global_asm!("", options(readonly)); -//~^ ERROR expected one of +//~^ ERROR the `readonly` option cannot be used with `global_asm!` global_asm!("", options(noreturn)); -//~^ ERROR expected one of +//~^ ERROR the `noreturn` option cannot be used with `global_asm!` global_asm!("", options(pure)); -//~^ ERROR expected one of +//~^ ERROR the `pure` option cannot be used with `global_asm!` global_asm!("", options(nostack)); -//~^ ERROR expected one of +//~^ ERROR the `nostack` option cannot be used with `global_asm!` global_asm!("", options(preserves_flags)); -//~^ ERROR expected one of +//~^ ERROR the `preserves_flags` option cannot be used with `global_asm!` diff --git a/tests/ui/asm/x86_64/bad-options.stderr b/tests/ui/asm/x86_64/bad-options.stderr index aa167e7913c..366eb7cb90f 100644 --- a/tests/ui/asm/x86_64/bad-options.stderr +++ b/tests/ui/asm/x86_64/bad-options.stderr @@ -51,41 +51,41 @@ LL | asm!("{}", out(reg) foo, clobber_abi("C"), clobber_abi("C")); | | clobber_abi | generic outputs -error: expected one of `)`, `att_syntax`, or `raw`, found `nomem` +error: the `nomem` option cannot be used with `global_asm!` --> $DIR/bad-options.rs:35:25 | LL | global_asm!("", options(nomem)); - | ^^^^^ expected one of `)`, `att_syntax`, or `raw` + | ^^^^^ the `nomem` option is not meaningful for global-scoped inline assembly -error: expected one of `)`, `att_syntax`, or `raw`, found `readonly` +error: the `readonly` option cannot be used with `global_asm!` --> $DIR/bad-options.rs:37:25 | LL | global_asm!("", options(readonly)); - | ^^^^^^^^ expected one of `)`, `att_syntax`, or `raw` + | ^^^^^^^^ the `readonly` option is not meaningful for global-scoped inline assembly -error: expected one of `)`, `att_syntax`, or `raw`, found `noreturn` +error: the `noreturn` option cannot be used with `global_asm!` --> $DIR/bad-options.rs:39:25 | LL | global_asm!("", options(noreturn)); - | ^^^^^^^^ expected one of `)`, `att_syntax`, or `raw` + | ^^^^^^^^ the `noreturn` option is not meaningful for global-scoped inline assembly -error: expected one of `)`, `att_syntax`, or `raw`, found `pure` +error: the `pure` option cannot be used with `global_asm!` --> $DIR/bad-options.rs:41:25 | LL | global_asm!("", options(pure)); - | ^^^^ expected one of `)`, `att_syntax`, or `raw` + | ^^^^ the `pure` option is not meaningful for global-scoped inline assembly -error: expected one of `)`, `att_syntax`, or `raw`, found `nostack` +error: the `nostack` option cannot be used with `global_asm!` --> $DIR/bad-options.rs:43:25 | LL | global_asm!("", options(nostack)); - | ^^^^^^^ expected one of `)`, `att_syntax`, or `raw` + | ^^^^^^^ the `nostack` option is not meaningful for global-scoped inline assembly -error: expected one of `)`, `att_syntax`, or `raw`, found `preserves_flags` +error: the `preserves_flags` option cannot be used with `global_asm!` --> $DIR/bad-options.rs:45:25 | LL | global_asm!("", options(preserves_flags)); - | ^^^^^^^^^^^^^^^ expected one of `)`, `att_syntax`, or `raw` + | ^^^^^^^^^^^^^^^ the `preserves_flags` option is not meaningful for global-scoped inline assembly error: invalid ABI for `clobber_abi` --> $DIR/bad-options.rs:24:18 diff --git a/tests/ui/associated-inherent-types/type-alias-bounds-are-enforced.rs b/tests/ui/associated-inherent-types/type-alias-bounds-are-enforced.rs deleted file mode 100644 index 5ac7e1e58b8..00000000000 --- a/tests/ui/associated-inherent-types/type-alias-bounds-are-enforced.rs +++ /dev/null @@ -1,20 +0,0 @@ -//@ compile-flags: --crate-type=lib -//@ check-pass - -#![feature(inherent_associated_types)] -#![allow(incomplete_features)] - -// Bounds on the self type play a major role in the resolution of inherent associated types (*). -// As a result of that, if a type alias contains any then its bounds have to be respected and the -// lint `type_alias_bounds` should not fire. - -#![deny(type_alias_bounds)] - -pub type Alias<T: Bound> = (Source<T>::Assoc,); - -pub struct Source<T>(T); -pub trait Bound {} - -impl<T: Bound> Source<T> { - pub type Assoc = (); -} diff --git a/tests/ui/associated-inherent-types/type-alias-bounds.rs b/tests/ui/associated-inherent-types/type-alias-bounds.rs new file mode 100644 index 00000000000..61641a83994 --- /dev/null +++ b/tests/ui/associated-inherent-types/type-alias-bounds.rs @@ -0,0 +1,29 @@ +//@ compile-flags: --crate-type=lib +//@ check-pass + +#![feature(inherent_associated_types)] +#![allow(incomplete_features)] + +// FIXME(inherent_associated_types): +// While we currently do take some clauses of the ParamEnv into consideration +// when performing IAT selection, we do not perform full well-formedness checking +// for (eager) type alias definition and usage sites. +// +// Therefore it's *correct* for lint `type_alias_bounds` to fire here despite the +// fact that removing `Bound` from `T` in `Alias` would lead to an error! +// +// Obviously, the present situation isn't ideal and we should fix it in one way +// or another. Either we somehow delay IAT selection until after HIR ty lowering +// to avoid the need to specify any bounds inside (eager) type aliases or we +// force the overarching type alias to be *lazy* (similar to TAITs) which would +// automatically lead to full wfchecking and lint TAB getting suppressed. + +pub type Alias<T: Bound> = (Source<T>::Assoc,); +//~^ WARN bounds on generic parameters in type aliases are not enforced + +pub struct Source<T>(T); +pub trait Bound {} + +impl<T: Bound> Source<T> { + pub type Assoc = (); +} diff --git a/tests/ui/associated-inherent-types/type-alias-bounds.stderr b/tests/ui/associated-inherent-types/type-alias-bounds.stderr new file mode 100644 index 00000000000..c56dd498f77 --- /dev/null +++ b/tests/ui/associated-inherent-types/type-alias-bounds.stderr @@ -0,0 +1,16 @@ +warning: bounds on generic parameters in type aliases are not enforced + --> $DIR/type-alias-bounds.rs:21:19 + | +LL | pub type Alias<T: Bound> = (Source<T>::Assoc,); + | --^^^^^ + | | | + | | will not be checked at usage sites of the type alias + | help: remove this bound + | + = note: this is a known limitation of the type checker that may be lifted in a future edition. + see issue #112792 <https://github.com/rust-lang/rust/issues/112792> for more information + = help: add `#![feature(lazy_type_alias)]` to the crate attributes to enable the desired semantics + = note: `#[warn(type_alias_bounds)]` on by default + +warning: 1 warning emitted + diff --git a/tests/ui/associated-type-bounds/type-alias.stderr b/tests/ui/associated-type-bounds/type-alias.stderr index 072c471467c..d59952b4a14 100644 --- a/tests/ui/associated-type-bounds/type-alias.stderr +++ b/tests/ui/associated-type-bounds/type-alias.stderr @@ -1,147 +1,159 @@ -warning: where clauses are not enforced in type aliases +warning: where clauses on type aliases are not enforced --> $DIR/type-alias.rs:3:25 | LL | type _TaWhere1<T> where T: Iterator<Item: Copy> = T; - | ^^^^^^^^^^^^^^^^^^^^^^^ - | + | ------^^^^^^^^^^^^^^^^^^^^^^^ + | | | + | | will not be checked at usage sites of the type alias + | help: remove this where clause + | + = note: this is a known limitation of the type checker that may be lifted in a future edition. + see issue #112792 <https://github.com/rust-lang/rust/issues/112792> for more information + = help: add `#![feature(lazy_type_alias)]` to the crate attributes to enable the desired semantics = note: `#[warn(type_alias_bounds)]` on by default -help: the clause will not be checked when the type alias is used, and should be removed - | -LL - type _TaWhere1<T> where T: Iterator<Item: Copy> = T; -LL + type _TaWhere1<T> = T; - | -warning: where clauses are not enforced in type aliases +warning: where clauses on type aliases are not enforced --> $DIR/type-alias.rs:4:25 | LL | type _TaWhere2<T> where T: Iterator<Item: 'static> = T; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ - | -help: the clause will not be checked when the type alias is used, and should be removed - | -LL - type _TaWhere2<T> where T: Iterator<Item: 'static> = T; -LL + type _TaWhere2<T> = T; - | + | ------^^^^^^^^^^^^^^^^^^^^^^^^^^ + | | | + | | will not be checked at usage sites of the type alias + | help: remove this where clause + | + = note: this is a known limitation of the type checker that may be lifted in a future edition. + see issue #112792 <https://github.com/rust-lang/rust/issues/112792> for more information + = help: add `#![feature(lazy_type_alias)]` to the crate attributes to enable the desired semantics -warning: where clauses are not enforced in type aliases +warning: where clauses on type aliases are not enforced --> $DIR/type-alias.rs:5:25 | LL | type _TaWhere3<T> where T: Iterator<Item: 'static> = T; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ - | -help: the clause will not be checked when the type alias is used, and should be removed - | -LL - type _TaWhere3<T> where T: Iterator<Item: 'static> = T; -LL + type _TaWhere3<T> = T; - | + | ------^^^^^^^^^^^^^^^^^^^^^^^^^^ + | | | + | | will not be checked at usage sites of the type alias + | help: remove this where clause + | + = note: this is a known limitation of the type checker that may be lifted in a future edition. + see issue #112792 <https://github.com/rust-lang/rust/issues/112792> for more information + = help: add `#![feature(lazy_type_alias)]` to the crate attributes to enable the desired semantics -warning: where clauses are not enforced in type aliases +warning: where clauses on type aliases are not enforced --> $DIR/type-alias.rs:6:25 | LL | type _TaWhere4<T> where T: Iterator<Item: 'static + Copy + Send> = T; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | -help: the clause will not be checked when the type alias is used, and should be removed - | -LL - type _TaWhere4<T> where T: Iterator<Item: 'static + Copy + Send> = T; -LL + type _TaWhere4<T> = T; - | + | ------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | | | + | | will not be checked at usage sites of the type alias + | help: remove this where clause + | + = note: this is a known limitation of the type checker that may be lifted in a future edition. + see issue #112792 <https://github.com/rust-lang/rust/issues/112792> for more information + = help: add `#![feature(lazy_type_alias)]` to the crate attributes to enable the desired semantics -warning: where clauses are not enforced in type aliases +warning: where clauses on type aliases are not enforced --> $DIR/type-alias.rs:7:25 | LL | type _TaWhere5<T> where T: Iterator<Item: for<'a> Into<&'a u8>> = T; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | -help: the clause will not be checked when the type alias is used, and should be removed - | -LL - type _TaWhere5<T> where T: Iterator<Item: for<'a> Into<&'a u8>> = T; -LL + type _TaWhere5<T> = T; - | + | ------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | | | + | | will not be checked at usage sites of the type alias + | help: remove this where clause + | + = note: this is a known limitation of the type checker that may be lifted in a future edition. + see issue #112792 <https://github.com/rust-lang/rust/issues/112792> for more information + = help: add `#![feature(lazy_type_alias)]` to the crate attributes to enable the desired semantics -warning: where clauses are not enforced in type aliases +warning: where clauses on type aliases are not enforced --> $DIR/type-alias.rs:8:25 | LL | type _TaWhere6<T> where T: Iterator<Item: Iterator<Item: Copy>> = T; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | -help: the clause will not be checked when the type alias is used, and should be removed - | -LL - type _TaWhere6<T> where T: Iterator<Item: Iterator<Item: Copy>> = T; -LL + type _TaWhere6<T> = T; - | + | ------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | | | + | | will not be checked at usage sites of the type alias + | help: remove this where clause + | + = note: this is a known limitation of the type checker that may be lifted in a future edition. + see issue #112792 <https://github.com/rust-lang/rust/issues/112792> for more information + = help: add `#![feature(lazy_type_alias)]` to the crate attributes to enable the desired semantics -warning: bounds on generic parameters are not enforced in type aliases +warning: bounds on generic parameters in type aliases are not enforced --> $DIR/type-alias.rs:10:20 | LL | type _TaInline1<T: Iterator<Item: Copy>> = T; - | ^^^^^^^^^^^^^^^^^^^^ - | -help: the bound will not be checked when the type alias is used, and should be removed - | -LL - type _TaInline1<T: Iterator<Item: Copy>> = T; -LL + type _TaInline1<T> = T; - | + | --^^^^^^^^^^^^^^^^^^^^ + | | | + | | will not be checked at usage sites of the type alias + | help: remove this bound + | + = note: this is a known limitation of the type checker that may be lifted in a future edition. + see issue #112792 <https://github.com/rust-lang/rust/issues/112792> for more information + = help: add `#![feature(lazy_type_alias)]` to the crate attributes to enable the desired semantics -warning: bounds on generic parameters are not enforced in type aliases +warning: bounds on generic parameters in type aliases are not enforced --> $DIR/type-alias.rs:11:20 | LL | type _TaInline2<T: Iterator<Item: 'static>> = T; - | ^^^^^^^^^^^^^^^^^^^^^^^ - | -help: the bound will not be checked when the type alias is used, and should be removed - | -LL - type _TaInline2<T: Iterator<Item: 'static>> = T; -LL + type _TaInline2<T> = T; - | + | --^^^^^^^^^^^^^^^^^^^^^^^ + | | | + | | will not be checked at usage sites of the type alias + | help: remove this bound + | + = note: this is a known limitation of the type checker that may be lifted in a future edition. + see issue #112792 <https://github.com/rust-lang/rust/issues/112792> for more information + = help: add `#![feature(lazy_type_alias)]` to the crate attributes to enable the desired semantics -warning: bounds on generic parameters are not enforced in type aliases +warning: bounds on generic parameters in type aliases are not enforced --> $DIR/type-alias.rs:12:20 | LL | type _TaInline3<T: Iterator<Item: 'static>> = T; - | ^^^^^^^^^^^^^^^^^^^^^^^ - | -help: the bound will not be checked when the type alias is used, and should be removed - | -LL - type _TaInline3<T: Iterator<Item: 'static>> = T; -LL + type _TaInline3<T> = T; - | + | --^^^^^^^^^^^^^^^^^^^^^^^ + | | | + | | will not be checked at usage sites of the type alias + | help: remove this bound + | + = note: this is a known limitation of the type checker that may be lifted in a future edition. + see issue #112792 <https://github.com/rust-lang/rust/issues/112792> for more information + = help: add `#![feature(lazy_type_alias)]` to the crate attributes to enable the desired semantics -warning: bounds on generic parameters are not enforced in type aliases +warning: bounds on generic parameters in type aliases are not enforced --> $DIR/type-alias.rs:13:20 | LL | type _TaInline4<T: Iterator<Item: 'static + Copy + Send>> = T; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | -help: the bound will not be checked when the type alias is used, and should be removed - | -LL - type _TaInline4<T: Iterator<Item: 'static + Copy + Send>> = T; -LL + type _TaInline4<T> = T; - | + | --^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | | | + | | will not be checked at usage sites of the type alias + | help: remove this bound + | + = note: this is a known limitation of the type checker that may be lifted in a future edition. + see issue #112792 <https://github.com/rust-lang/rust/issues/112792> for more information + = help: add `#![feature(lazy_type_alias)]` to the crate attributes to enable the desired semantics -warning: bounds on generic parameters are not enforced in type aliases +warning: bounds on generic parameters in type aliases are not enforced --> $DIR/type-alias.rs:14:20 | LL | type _TaInline5<T: Iterator<Item: for<'a> Into<&'a u8>>> = T; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | -help: the bound will not be checked when the type alias is used, and should be removed - | -LL - type _TaInline5<T: Iterator<Item: for<'a> Into<&'a u8>>> = T; -LL + type _TaInline5<T> = T; - | + | --^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | | | + | | will not be checked at usage sites of the type alias + | help: remove this bound + | + = note: this is a known limitation of the type checker that may be lifted in a future edition. + see issue #112792 <https://github.com/rust-lang/rust/issues/112792> for more information + = help: add `#![feature(lazy_type_alias)]` to the crate attributes to enable the desired semantics -warning: bounds on generic parameters are not enforced in type aliases +warning: bounds on generic parameters in type aliases are not enforced --> $DIR/type-alias.rs:15:20 | LL | type _TaInline6<T: Iterator<Item: Iterator<Item: Copy>>> = T; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | -help: the bound will not be checked when the type alias is used, and should be removed - | -LL - type _TaInline6<T: Iterator<Item: Iterator<Item: Copy>>> = T; -LL + type _TaInline6<T> = T; - | + | --^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | | | + | | will not be checked at usage sites of the type alias + | help: remove this bound + | + = note: this is a known limitation of the type checker that may be lifted in a future edition. + see issue #112792 <https://github.com/rust-lang/rust/issues/112792> for more information + = help: add `#![feature(lazy_type_alias)]` to the crate attributes to enable the desired semantics warning: 12 warnings emitted diff --git a/tests/ui/associated-types/associated-types-outlives.stderr b/tests/ui/associated-types/associated-types-outlives.stderr index c97af672c33..1164869bf19 100644 --- a/tests/ui/associated-types/associated-types-outlives.stderr +++ b/tests/ui/associated-types/associated-types-outlives.stderr @@ -11,10 +11,14 @@ LL | drop(x); LL | return f(y); | - borrow later used here | -help: consider cloning the value if the performance cost is acceptable +help: if `T` implemented `Clone`, you could clone the value + --> $DIR/associated-types-outlives.rs:17:21 | -LL | 's: loop { y = denormalise(&x).clone(); break } - | ++++++++ +LL | pub fn free_and_use<T: for<'a> Foo<'a>, + | ^ consider constraining this type parameter with `Clone` +... +LL | 's: loop { y = denormalise(&x); break } + | -- you could clone this value error: aborting due to 1 previous error diff --git a/tests/ui/async-await/async-closures/clone-closure.rs b/tests/ui/async-await/async-closures/clone-closure.rs new file mode 100644 index 00000000000..807897e3e03 --- /dev/null +++ b/tests/ui/async-await/async-closures/clone-closure.rs @@ -0,0 +1,24 @@ +//@ aux-build:block-on.rs +//@ edition:2021 +//@ run-pass +//@ check-run-results + +#![feature(async_closure)] + +extern crate block_on; + +async fn for_each(f: impl async FnOnce(&str) + Clone) { + f.clone()("world").await; + f.clone()("world2").await; +} + +fn main() { + block_on::block_on(async_main()); +} + +async fn async_main() { + let x = String::from("Hello,"); + for_each(async move |s| { + println!("{x} {s}"); + }).await; +} diff --git a/tests/ui/async-await/async-closures/clone-closure.run.stdout b/tests/ui/async-await/async-closures/clone-closure.run.stdout new file mode 100644 index 00000000000..0cfcf1923da --- /dev/null +++ b/tests/ui/async-await/async-closures/clone-closure.run.stdout @@ -0,0 +1,2 @@ +Hello, world +Hello, world2 diff --git a/tests/ui/async-await/async-closures/move-consuming-capture.stderr b/tests/ui/async-await/async-closures/move-consuming-capture.stderr index 45c1eac8f8f..4ce71ec49d6 100644 --- a/tests/ui/async-await/async-closures/move-consuming-capture.stderr +++ b/tests/ui/async-await/async-closures/move-consuming-capture.stderr @@ -11,6 +11,15 @@ LL | x().await; | note: `async_call_once` takes ownership of the receiver `self`, which moves `x` --> $SRC_DIR/core/src/ops/async_function.rs:LL:COL +help: you could `clone` the value and consume it, if the `NoCopy: Clone` trait bound could be satisfied + | +LL | x.clone()().await; + | ++++++++ +help: consider annotating `NoCopy` with `#[derive(Clone)]` + | +LL + #[derive(Clone)] +LL | struct NoCopy; + | error: aborting due to 1 previous error diff --git a/tests/ui/async-await/async-closures/not-clone-closure.rs b/tests/ui/async-await/async-closures/not-clone-closure.rs new file mode 100644 index 00000000000..2776ce4690f --- /dev/null +++ b/tests/ui/async-await/async-closures/not-clone-closure.rs @@ -0,0 +1,36 @@ +//@ edition: 2021 + +#![feature(async_closure)] + +struct NotClonableArg; +#[derive(Default)] +struct NotClonableReturnType; + +// Verify that the only components that we care about are the upvars, not the signature. +fn we_are_okay_with_not_clonable_signature() { + let x = async |x: NotClonableArg| -> NotClonableReturnType { Default::default() }; + x.clone(); // Okay +} + +#[derive(Debug)] +struct NotClonableUpvar; + +fn we_only_care_about_clonable_upvars() { + let x = NotClonableUpvar; + // Notably, this is clone because we capture `&x`. + let yes_clone = async || { + println!("{x:?}"); + }; + yes_clone.clone(); // Okay + + let z = NotClonableUpvar; + // However, this is not because the closure captures `z` by move. + // (Even though the future that is lent out captures `z by ref!) + let not_clone = async move || { + println!("{z:?}"); + }; + not_clone.clone(); + //~^ ERROR the trait bound `NotClonableUpvar: Clone` is not satisfied +} + +fn main() {} diff --git a/tests/ui/async-await/async-closures/not-clone-closure.stderr b/tests/ui/async-await/async-closures/not-clone-closure.stderr new file mode 100644 index 00000000000..aea48a455c2 --- /dev/null +++ b/tests/ui/async-await/async-closures/not-clone-closure.stderr @@ -0,0 +1,20 @@ +error[E0277]: the trait bound `NotClonableUpvar: Clone` is not satisfied in `{async closure@$DIR/not-clone-closure.rs:29:21: 29:34}` + --> $DIR/not-clone-closure.rs:32:15 + | +LL | not_clone.clone(); + | ^^^^^ within `{async closure@$DIR/not-clone-closure.rs:29:21: 29:34}`, the trait `Clone` is not implemented for `NotClonableUpvar`, which is required by `{async closure@$DIR/not-clone-closure.rs:29:21: 29:34}: Clone` + | +note: required because it's used within this closure + --> $DIR/not-clone-closure.rs:29:21 + | +LL | let not_clone = async move || { + | ^^^^^^^^^^^^^ +help: consider annotating `NotClonableUpvar` with `#[derive(Clone)]` + | +LL + #[derive(Clone)] +LL | struct NotClonableUpvar; + | + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/async-await/async-closures/without-precise-captures-we-are-powerless.rs b/tests/ui/async-await/async-closures/without-precise-captures-we-are-powerless.rs index 17681161e20..18f16ca4b2d 100644 --- a/tests/ui/async-await/async-closures/without-precise-captures-we-are-powerless.rs +++ b/tests/ui/async-await/async-closures/without-precise-captures-we-are-powerless.rs @@ -19,7 +19,7 @@ fn simple<'a>(x: &'a i32) { let c = async move || { println!("{}", *x); }; outlives::<'a>(c()); //~ ERROR `c` does not live long enough - outlives::<'a>(call_once(c)); //~ ERROR cannot move out of `c` + outlives::<'a>(call_once(c)); } struct S<'a>(&'a i32); diff --git a/tests/ui/async-await/async-closures/without-precise-captures-we-are-powerless.stderr b/tests/ui/async-await/async-closures/without-precise-captures-we-are-powerless.stderr index 569028934cb..1df5abdbb18 100644 --- a/tests/ui/async-await/async-closures/without-precise-captures-we-are-powerless.stderr +++ b/tests/ui/async-await/async-closures/without-precise-captures-we-are-powerless.stderr @@ -29,22 +29,6 @@ LL | outlives::<'a>(call_once(c)); LL | } | - `c` dropped here while still borrowed -error[E0505]: cannot move out of `c` because it is borrowed - --> $DIR/without-precise-captures-we-are-powerless.rs:22:30 - | -LL | fn simple<'a>(x: &'a i32) { - | -- lifetime `'a` defined here -... -LL | let c = async move || { println!("{}", *x); }; - | - binding `c` declared here -LL | outlives::<'a>(c()); - | --- - | | - | borrow of `c` occurs here - | argument requires that `c` is borrowed for `'a` -LL | outlives::<'a>(call_once(c)); - | ^ move out of `c` occurs here - error[E0597]: `x` does not live long enough --> $DIR/without-precise-captures-we-are-powerless.rs:28:13 | @@ -146,7 +130,7 @@ LL | // outlives::<'a>(call_once(c)); // FIXME(async_closures): Figure out w LL | } | - `c` dropped here while still borrowed -error: aborting due to 10 previous errors +error: aborting due to 9 previous errors Some errors have detailed explanations: E0505, E0597, E0621. For more information about an error, try `rustc --explain E0505`. diff --git a/tests/ui/const-generics/generic_const_exprs/type-alias-bounds.neg.stderr b/tests/ui/const-generics/generic_const_exprs/type-alias-bounds.neg.stderr new file mode 100644 index 00000000000..fa12dd14753 --- /dev/null +++ b/tests/ui/const-generics/generic_const_exprs/type-alias-bounds.neg.stderr @@ -0,0 +1,63 @@ +error[E0277]: the trait bound `String: Copy` is not satisfied + --> $DIR/type-alias-bounds.rs:23:12 + | +LL | let _: AliasConstUnused<String>; + | ^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `String` + | +note: required by a bound in `ct_unused_0::AliasConstUnused` + --> $DIR/type-alias-bounds.rs:20:30 + | +LL | type AliasConstUnused<T: Copy> = (T, I32<{ DATA }>); + | ^^^^ required by this bound in `AliasConstUnused` + +error[E0277]: the trait bound `String: Copy` is not satisfied + --> $DIR/type-alias-bounds.rs:31:12 + | +LL | let _: AliasConstUnused; + | ^^^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `String` + | +note: required by a bound in `ct_unused_1::AliasConstUnused` + --> $DIR/type-alias-bounds.rs:29:41 + | +LL | type AliasConstUnused where String: Copy = I32<{ 0; 0 }>; + | ^^^^ required by this bound in `AliasConstUnused` + +error[E0277]: the trait bound `String: Copy` is not satisfied + --> $DIR/type-alias-bounds.rs:39:12 + | +LL | let _: AliasFnUnused<String>; + | ^^^^^^^^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `String` + | +note: required by a bound in `AliasFnUnused` + --> $DIR/type-alias-bounds.rs:36:27 + | +LL | type AliasFnUnused<T: Copy> = (T, I32<{ code() }>); + | ^^^^ required by this bound in `AliasFnUnused` + +error[E0277]: the trait bound `String: Copy` is not satisfied + --> $DIR/type-alias-bounds.rs:57:12 + | +LL | let _: AliasAssocConstUsed<String>; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `String` + | +note: required by a bound in `AliasAssocConstUsed` + --> $DIR/type-alias-bounds.rs:55:41 + | +LL | type AliasAssocConstUsed<T: Trait + Copy> = I32<{ T::DATA }>; + | ^^^^ required by this bound in `AliasAssocConstUsed` + +error[E0277]: the trait bound `String: Copy` is not satisfied + --> $DIR/type-alias-bounds.rs:65:12 + | +LL | let _: AliasFnUsed<String>; + | ^^^^^^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `String` + | +note: required by a bound in `AliasFnUsed` + --> $DIR/type-alias-bounds.rs:62:33 + | +LL | type AliasFnUsed<T: Trait + Copy> = I32<{ code::<T>() }>; + | ^^^^ required by this bound in `AliasFnUsed` + +error: aborting due to 5 previous errors + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/const-generics/generic_const_exprs/type-alias-bounds.rs b/tests/ui/const-generics/generic_const_exprs/type-alias-bounds.rs new file mode 100644 index 00000000000..f16e646129c --- /dev/null +++ b/tests/ui/const-generics/generic_const_exprs/type-alias-bounds.rs @@ -0,0 +1,71 @@ +//@ revisions: pos neg +//@[pos] check-pass + +#![feature(generic_const_exprs)] +#![feature(trivial_bounds)] // only used in test case `ct_unused_1` +#![allow(incomplete_features)] + +// FIXME(generic_const_exprs): Revisit this before stabilization. +// Check that we don't emit the lint `type_alias_bounds` for (eager) type aliases +// whose RHS contains a const projection (aka uneval'ed const). +// Since anon consts inherit the parent generics and predicates and we effectively +// check them before and after instantiaton for well-formedness, the type alias +// bounds are in every sense "enforced". +// Note that the test cases whose name ends in "unused" just demonstrate that this +// holds even if the const projections don't "visibly" capture any generics and/or +// predicates. +#![deny(type_alias_bounds)] + +fn ct_unused_0() { + type AliasConstUnused<T: Copy> = (T, I32<{ DATA }>); + const DATA: i32 = 0; + #[cfg(neg)] + let _: AliasConstUnused<String>; + //[neg]~^ ERROR the trait bound `String: Copy` is not satisfied +} + +fn ct_unused_1() { + #[allow(trivial_bounds)] + type AliasConstUnused where String: Copy = I32<{ 0; 0 }>; + #[cfg(neg)] + let _: AliasConstUnused; + //[neg]~^ ERROR the trait bound `String: Copy` is not satisfied +} + +fn fn_unused() { + type AliasFnUnused<T: Copy> = (T, I32<{ code() }>); + const fn code() -> i32 { 0 } + #[cfg(neg)] + let _: AliasFnUnused<String>; + //[neg]~^ ERROR the trait bound `String: Copy` is not satisfied +} + +trait Trait { + type Proj; + const DATA: i32; +} + +impl Trait for String { + type Proj = i32; + const DATA: i32 = 0; +} + +// Regression test for issue #94398. +fn assoc_ct_used() { + type AliasAssocConstUsed<T: Trait + Copy> = I32<{ T::DATA }>; + #[cfg(neg)] + let _: AliasAssocConstUsed<String>; + //[neg]~^ ERROR the trait bound `String: Copy` is not satisfied +} + +fn fn_used() { + type AliasFnUsed<T: Trait + Copy> = I32<{ code::<T>() }>; + const fn code<T: Trait>() -> i32 { T::DATA } + #[cfg(neg)] + let _: AliasFnUsed<String>; + //[neg]~^ ERROR the trait bound `String: Copy` is not satisfied +} + +struct I32<const N: i32>; + +fn main() {} diff --git a/tests/ui/consts/const-eval/parse_ints.rs b/tests/ui/consts/const-eval/parse_ints.rs index ff9fc47e65c..cb9a3eb4312 100644 --- a/tests/ui/consts/const-eval/parse_ints.rs +++ b/tests/ui/consts/const-eval/parse_ints.rs @@ -1,5 +1,3 @@ -#![feature(const_int_from_str)] - const _OK: () = match i32::from_str_radix("-1234", 10) { Ok(x) => assert!(x == -1234), Err(_) => panic!(), diff --git a/tests/ui/consts/const-eval/parse_ints.stderr b/tests/ui/consts/const-eval/parse_ints.stderr index 9e49fe433a1..ec9249ece8e 100644 --- a/tests/ui/consts/const-eval/parse_ints.stderr +++ b/tests/ui/consts/const-eval/parse_ints.stderr @@ -6,7 +6,7 @@ error[E0080]: evaluation of constant value failed note: inside `core::num::<impl u64>::from_str_radix` --> $SRC_DIR/core/src/num/mod.rs:LL:COL note: inside `_TOO_LOW` - --> $DIR/parse_ints.rs:7:24 + --> $DIR/parse_ints.rs:5:24 | LL | const _TOO_LOW: () = { u64::from_str_radix("12345ABCD", 1); }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -20,7 +20,7 @@ error[E0080]: evaluation of constant value failed note: inside `core::num::<impl u64>::from_str_radix` --> $SRC_DIR/core/src/num/mod.rs:LL:COL note: inside `_TOO_HIGH` - --> $DIR/parse_ints.rs:8:25 + --> $DIR/parse_ints.rs:6:25 | LL | const _TOO_HIGH: () = { u64::from_str_radix("12345ABCD", 37); }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/consts/packed_pattern.stderr b/tests/ui/consts/packed_pattern.stderr index 9ca50a95e4e..a0b434b2d78 100644 --- a/tests/ui/consts/packed_pattern.stderr +++ b/tests/ui/consts/packed_pattern.stderr @@ -1,8 +1,10 @@ warning: unreachable pattern --> $DIR/packed_pattern.rs:16:9 | +LL | Foo { field: (5, 6, 7, 8) } => {}, + | --------------------------- matches all the values already LL | FOO => unreachable!(), - | ^^^ + | ^^^ unreachable pattern | = note: `#[warn(unreachable_patterns)]` on by default diff --git a/tests/ui/consts/packed_pattern2.stderr b/tests/ui/consts/packed_pattern2.stderr index 4dc54461eeb..4785f4d0297 100644 --- a/tests/ui/consts/packed_pattern2.stderr +++ b/tests/ui/consts/packed_pattern2.stderr @@ -1,8 +1,10 @@ warning: unreachable pattern --> $DIR/packed_pattern2.rs:24:9 | +LL | Bar { a: Foo { field: (5, 6) } } => {}, + | -------------------------------- matches all the values already LL | FOO => unreachable!(), - | ^^^ + | ^^^ unreachable pattern | = note: `#[warn(unreachable_patterns)]` on by default diff --git a/tests/ui/error-codes/E0001.stderr b/tests/ui/error-codes/E0001.stderr index 49bb73e7ba8..40008230ec8 100644 --- a/tests/ui/error-codes/E0001.stderr +++ b/tests/ui/error-codes/E0001.stderr @@ -2,8 +2,17 @@ error: unreachable pattern --> $DIR/E0001.rs:8:9 | LL | _ => {/* ... */} - | ^ + | ^ unreachable pattern | +note: these patterns collectively make the last one unreachable + --> $DIR/E0001.rs:8:9 + | +LL | Some(_) => {/* ... */} + | ------- matches some of the same values +LL | None => {/* ... */} + | ---- matches some of the same values +LL | _ => {/* ... */} + | ^ collectively making this unreachable note: the lint level is defined here --> $DIR/E0001.rs:1:9 | diff --git a/tests/ui/feature-gates/feature-gate-is_sorted.rs b/tests/ui/feature-gates/feature-gate-is_sorted.rs deleted file mode 100644 index 359ed835bcb..00000000000 --- a/tests/ui/feature-gates/feature-gate-is_sorted.rs +++ /dev/null @@ -1,13 +0,0 @@ -fn main() { - // Assert `Iterator` methods are unstable - assert!([1, 2, 2, 9].iter().is_sorted()); - //~^ ERROR: use of unstable library feature 'is_sorted': new API - assert!(![-2i32, -1, 0, 3].iter().is_sorted_by_key(|n| n.abs())); - //~^ ERROR: use of unstable library feature 'is_sorted': new API - - // Assert `[T]` methods are unstable - assert!([1, 2, 2, 9].is_sorted()); - //~^ ERROR: use of unstable library feature 'is_sorted': new API - assert!(![-2i32, -1, 0, 3].is_sorted_by_key(|n| n.abs())); - //~^ ERROR: use of unstable library feature 'is_sorted': new API -} diff --git a/tests/ui/feature-gates/feature-gate-is_sorted.stderr b/tests/ui/feature-gates/feature-gate-is_sorted.stderr deleted file mode 100644 index f3e87659b02..00000000000 --- a/tests/ui/feature-gates/feature-gate-is_sorted.stderr +++ /dev/null @@ -1,43 +0,0 @@ -error[E0658]: use of unstable library feature 'is_sorted': new API - --> $DIR/feature-gate-is_sorted.rs:3:33 - | -LL | assert!([1, 2, 2, 9].iter().is_sorted()); - | ^^^^^^^^^ - | - = note: see issue #53485 <https://github.com/rust-lang/rust/issues/53485> for more information - = help: add `#![feature(is_sorted)]` to the crate attributes to enable - = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date - -error[E0658]: use of unstable library feature 'is_sorted': new API - --> $DIR/feature-gate-is_sorted.rs:5:39 - | -LL | assert!(![-2i32, -1, 0, 3].iter().is_sorted_by_key(|n| n.abs())); - | ^^^^^^^^^^^^^^^^ - | - = note: see issue #53485 <https://github.com/rust-lang/rust/issues/53485> for more information - = help: add `#![feature(is_sorted)]` to the crate attributes to enable - = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date - -error[E0658]: use of unstable library feature 'is_sorted': new API - --> $DIR/feature-gate-is_sorted.rs:9:26 - | -LL | assert!([1, 2, 2, 9].is_sorted()); - | ^^^^^^^^^ - | - = note: see issue #53485 <https://github.com/rust-lang/rust/issues/53485> for more information - = help: add `#![feature(is_sorted)]` to the crate attributes to enable - = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date - -error[E0658]: use of unstable library feature 'is_sorted': new API - --> $DIR/feature-gate-is_sorted.rs:11:32 - | -LL | assert!(![-2i32, -1, 0, 3].is_sorted_by_key(|n| n.abs())); - | ^^^^^^^^^^^^^^^^ - | - = note: see issue #53485 <https://github.com/rust-lang/rust/issues/53485> for more information - = help: add `#![feature(is_sorted)]` to the crate attributes to enable - = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date - -error: aborting due to 4 previous errors - -For more information about this error, try `rustc --explain E0658`. diff --git a/tests/ui/feature-gates/feature-gate-more-maybe-bounds.rs b/tests/ui/feature-gates/feature-gate-more-maybe-bounds.rs new file mode 100644 index 00000000000..debe143b091 --- /dev/null +++ b/tests/ui/feature-gates/feature-gate-more-maybe-bounds.rs @@ -0,0 +1,24 @@ +#![feature(auto_traits)] + +trait Trait1 {} +auto trait Trait2 {} +trait Trait3: ?Trait1 {} +//~^ ERROR `?Trait` is not permitted in supertraits +trait Trait4 where Self: ?Trait1 {} +//~^ ERROR ?Trait` bounds are only permitted at the point where a type parameter is declared + +fn foo(_: Box<dyn Trait1 + ?Trait2>) {} +//~^ ERROR `?Trait` is not permitted in trait object types +fn bar<T: ?Trait1 + ?Trait2>(_: T) {} +//~^ ERROR type parameter has more than one relaxed default bound, only one is supported +//~| WARN relaxing a default bound only does something for `?Sized`; all other traits are not bound by default +//~| WARN relaxing a default bound only does something for `?Sized`; all other traits are not bound by default + +trait Trait {} +// Do not suggest `#![feature(more_maybe_bounds)]` for repetitions +fn baz<T: ?Trait + ?Trait>(_ : T) {} +//~^ ERROR type parameter has more than one relaxed default bound, only one is supported +//~| WARN relaxing a default bound only does something for `?Sized`; all other traits are not bound by default +//~| WARN relaxing a default bound only does something for `?Sized`; all other traits are not bound by default + +fn main() {} diff --git a/tests/ui/feature-gates/feature-gate-more-maybe-bounds.stderr b/tests/ui/feature-gates/feature-gate-more-maybe-bounds.stderr new file mode 100644 index 00000000000..e6d65e05997 --- /dev/null +++ b/tests/ui/feature-gates/feature-gate-more-maybe-bounds.stderr @@ -0,0 +1,71 @@ +error[E0658]: `?Trait` is not permitted in supertraits + --> $DIR/feature-gate-more-maybe-bounds.rs:5:15 + | +LL | trait Trait3: ?Trait1 {} + | ^^^^^^^ + | + = note: traits are `?Trait1` by default + = help: add `#![feature(more_maybe_bounds)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: `?Trait` is not permitted in trait object types + --> $DIR/feature-gate-more-maybe-bounds.rs:10:28 + | +LL | fn foo(_: Box<dyn Trait1 + ?Trait2>) {} + | ^^^^^^^ + | + = help: add `#![feature(more_maybe_bounds)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: `?Trait` bounds are only permitted at the point where a type parameter is declared + --> $DIR/feature-gate-more-maybe-bounds.rs:7:26 + | +LL | trait Trait4 where Self: ?Trait1 {} + | ^^^^^^^ + | + = help: add `#![feature(more_maybe_bounds)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0203]: type parameter has more than one relaxed default bound, only one is supported + --> $DIR/feature-gate-more-maybe-bounds.rs:12:11 + | +LL | fn bar<T: ?Trait1 + ?Trait2>(_: T) {} + | ^^^^^^^ ^^^^^^^ + | + = help: add `#![feature(more_maybe_bounds)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +warning: relaxing a default bound only does something for `?Sized`; all other traits are not bound by default + --> $DIR/feature-gate-more-maybe-bounds.rs:12:11 + | +LL | fn bar<T: ?Trait1 + ?Trait2>(_: T) {} + | ^^^^^^^ + +warning: relaxing a default bound only does something for `?Sized`; all other traits are not bound by default + --> $DIR/feature-gate-more-maybe-bounds.rs:12:21 + | +LL | fn bar<T: ?Trait1 + ?Trait2>(_: T) {} + | ^^^^^^^ + +error[E0203]: type parameter has more than one relaxed default bound, only one is supported + --> $DIR/feature-gate-more-maybe-bounds.rs:19:11 + | +LL | fn baz<T: ?Trait + ?Trait>(_ : T) {} + | ^^^^^^ ^^^^^^ + +warning: relaxing a default bound only does something for `?Sized`; all other traits are not bound by default + --> $DIR/feature-gate-more-maybe-bounds.rs:19:11 + | +LL | fn baz<T: ?Trait + ?Trait>(_ : T) {} + | ^^^^^^ + +warning: relaxing a default bound only does something for `?Sized`; all other traits are not bound by default + --> $DIR/feature-gate-more-maybe-bounds.rs:19:20 + | +LL | fn baz<T: ?Trait + ?Trait>(_ : T) {} + | ^^^^^^ + +error: aborting due to 5 previous errors; 4 warnings emitted + +Some errors have detailed explanations: E0203, E0658. +For more information about an error, try `rustc --explain E0203`. diff --git a/tests/ui/lang-items/missing-clone-for-suggestion.rs b/tests/ui/lang-items/missing-clone-for-suggestion.rs deleted file mode 100644 index e8290c0098a..00000000000 --- a/tests/ui/lang-items/missing-clone-for-suggestion.rs +++ /dev/null @@ -1,20 +0,0 @@ -// Avoid panicking if the Clone trait is not found while building error suggestions -// See #104870 - -#![feature(no_core, lang_items)] -#![no_core] - -#[lang = "sized"] -trait Sized {} - -#[lang = "copy"] -trait Copy {} - -fn g<T>(x: T) {} - -fn f(x: *mut u8) { - g(x); - g(x); //~ ERROR use of moved value: `x` -} - -fn main() {} diff --git a/tests/ui/lang-items/missing-clone-for-suggestion.stderr b/tests/ui/lang-items/missing-clone-for-suggestion.stderr deleted file mode 100644 index 0187f965b5c..00000000000 --- a/tests/ui/lang-items/missing-clone-for-suggestion.stderr +++ /dev/null @@ -1,21 +0,0 @@ -error[E0382]: use of moved value: `x` - --> $DIR/missing-clone-for-suggestion.rs:17:7 - | -LL | fn f(x: *mut u8) { - | - move occurs because `x` has type `*mut u8`, which does not implement the `Copy` trait -LL | g(x); - | - value moved here -LL | g(x); - | ^ value used here after move - | -note: consider changing this parameter type in function `g` to borrow instead if owning the value isn't necessary - --> $DIR/missing-clone-for-suggestion.rs:13:12 - | -LL | fn g<T>(x: T) {} - | - ^ this parameter takes ownership of the value - | | - | in this function - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0382`. diff --git a/tests/ui/lint/dead-code/unused-impl-for-non-adts.rs b/tests/ui/lint/dead-code/unused-impl-for-non-adts.rs new file mode 100644 index 00000000000..46065dcee81 --- /dev/null +++ b/tests/ui/lint/dead-code/unused-impl-for-non-adts.rs @@ -0,0 +1,45 @@ +#![deny(dead_code)] + +struct Foo; //~ ERROR struct `Foo` is never constructed + +trait Trait { //~ ERROR trait `Trait` is never used + fn foo(&self) {} +} + +impl Trait for Foo {} + +impl Trait for [Foo] {} +impl<const N: usize> Trait for [Foo; N] {} + +impl Trait for *const Foo {} +impl Trait for *mut Foo {} + +impl Trait for &Foo {} +impl Trait for &&Foo {} +impl Trait for &mut Foo {} + +impl Trait for [&Foo] {} +impl Trait for &[Foo] {} +impl Trait for &*const Foo {} + +pub trait Trait2 { + fn foo(&self) {} +} + +impl Trait2 for Foo {} + +impl Trait2 for [Foo] {} +impl<const N: usize> Trait2 for [Foo; N] {} + +impl Trait2 for *const Foo {} +impl Trait2 for *mut Foo {} + +impl Trait2 for &Foo {} +impl Trait2 for &&Foo {} +impl Trait2 for &mut Foo {} + +impl Trait2 for [&Foo] {} +impl Trait2 for &[Foo] {} +impl Trait2 for &*const Foo {} + +fn main() {} diff --git a/tests/ui/lint/dead-code/unused-impl-for-non-adts.stderr b/tests/ui/lint/dead-code/unused-impl-for-non-adts.stderr new file mode 100644 index 00000000000..e61fc403e81 --- /dev/null +++ b/tests/ui/lint/dead-code/unused-impl-for-non-adts.stderr @@ -0,0 +1,20 @@ +error: struct `Foo` is never constructed + --> $DIR/unused-impl-for-non-adts.rs:3:8 + | +LL | struct Foo; + | ^^^ + | +note: the lint level is defined here + --> $DIR/unused-impl-for-non-adts.rs:1:9 + | +LL | #![deny(dead_code)] + | ^^^^^^^^^ + +error: trait `Trait` is never used + --> $DIR/unused-impl-for-non-adts.rs:5:7 + | +LL | trait Trait { + | ^^^^^ + +error: aborting due to 2 previous errors + diff --git a/tests/ui/macros/issue-118786.rs b/tests/ui/macros/issue-118786.rs index 97454c9de07..a41372e4ea8 100644 --- a/tests/ui/macros/issue-118786.rs +++ b/tests/ui/macros/issue-118786.rs @@ -7,6 +7,7 @@ macro_rules! make_macro { macro_rules! $macro_name { //~^ ERROR macro expansion ignores token `{` and any following //~| ERROR cannot find macro `macro_rules` in this scope + //~| put a macro name here () => {} } } diff --git a/tests/ui/macros/issue-118786.stderr b/tests/ui/macros/issue-118786.stderr index 03e65c94ba7..256b742ee16 100644 --- a/tests/ui/macros/issue-118786.stderr +++ b/tests/ui/macros/issue-118786.stderr @@ -1,5 +1,5 @@ error: macros that expand to items must be delimited with braces or followed by a semicolon - --> $DIR/issue-118786.rs:15:13 + --> $DIR/issue-118786.rs:16:13 | LL | make_macro!((meow)); | ^^^^^^ @@ -34,10 +34,10 @@ LL | make_macro!((meow)); | ------------------- in this macro invocation | note: maybe you have forgotten to define a name for this `macro_rules!` - --> $DIR/issue-118786.rs:7:9 + --> $DIR/issue-118786.rs:7:20 | LL | macro_rules! $macro_name { - | ^^^^^^^^^^^ + | ^ put a macro name here ... LL | make_macro!((meow)); | ------------------- in this macro invocation diff --git a/tests/ui/macros/macro-missing-fragment.stderr b/tests/ui/macros/macro-missing-fragment.e2015.stderr index abe4d4cd68a..a068dc5c054 100644 --- a/tests/ui/macros/macro-missing-fragment.stderr +++ b/tests/ui/macros/macro-missing-fragment.e2015.stderr @@ -1,11 +1,11 @@ error: missing fragment specifier - --> $DIR/macro-missing-fragment.rs:4:20 + --> $DIR/macro-missing-fragment.rs:9:20 | LL | ( $( any_token $field_rust_type )* ) => {}; | ^^^^^^^^^^^^^^^^ warning: missing fragment specifier - --> $DIR/macro-missing-fragment.rs:4:20 + --> $DIR/macro-missing-fragment.rs:9:20 | LL | ( $( any_token $field_rust_type )* ) => {}; | ^^^^^^^^^^^^^^^^ @@ -13,13 +13,13 @@ LL | ( $( any_token $field_rust_type )* ) => {}; = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #40107 <https://github.com/rust-lang/rust/issues/40107> note: the lint level is defined here - --> $DIR/macro-missing-fragment.rs:1:9 + --> $DIR/macro-missing-fragment.rs:6:9 | LL | #![warn(missing_fragment_specifier)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: missing fragment specifier - --> $DIR/macro-missing-fragment.rs:12:7 + --> $DIR/macro-missing-fragment.rs:19:7 | LL | ( $name ) => {}; | ^^^^^ @@ -28,7 +28,7 @@ LL | ( $name ) => {}; = note: for more information, see issue #40107 <https://github.com/rust-lang/rust/issues/40107> warning: missing fragment specifier - --> $DIR/macro-missing-fragment.rs:18:7 + --> $DIR/macro-missing-fragment.rs:26:7 | LL | ( $name ) => {}; | ^^^^^ @@ -40,7 +40,7 @@ error: aborting due to 1 previous error; 3 warnings emitted Future incompatibility report: Future breakage diagnostic: warning: missing fragment specifier - --> $DIR/macro-missing-fragment.rs:4:20 + --> $DIR/macro-missing-fragment.rs:9:20 | LL | ( $( any_token $field_rust_type )* ) => {}; | ^^^^^^^^^^^^^^^^ @@ -48,14 +48,14 @@ LL | ( $( any_token $field_rust_type )* ) => {}; = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #40107 <https://github.com/rust-lang/rust/issues/40107> note: the lint level is defined here - --> $DIR/macro-missing-fragment.rs:1:9 + --> $DIR/macro-missing-fragment.rs:6:9 | LL | #![warn(missing_fragment_specifier)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^ Future breakage diagnostic: warning: missing fragment specifier - --> $DIR/macro-missing-fragment.rs:12:7 + --> $DIR/macro-missing-fragment.rs:19:7 | LL | ( $name ) => {}; | ^^^^^ @@ -63,14 +63,14 @@ LL | ( $name ) => {}; = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #40107 <https://github.com/rust-lang/rust/issues/40107> note: the lint level is defined here - --> $DIR/macro-missing-fragment.rs:1:9 + --> $DIR/macro-missing-fragment.rs:6:9 | LL | #![warn(missing_fragment_specifier)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^ Future breakage diagnostic: warning: missing fragment specifier - --> $DIR/macro-missing-fragment.rs:18:7 + --> $DIR/macro-missing-fragment.rs:26:7 | LL | ( $name ) => {}; | ^^^^^ @@ -78,7 +78,7 @@ LL | ( $name ) => {}; = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #40107 <https://github.com/rust-lang/rust/issues/40107> note: the lint level is defined here - --> $DIR/macro-missing-fragment.rs:1:9 + --> $DIR/macro-missing-fragment.rs:6:9 | LL | #![warn(missing_fragment_specifier)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/macros/macro-missing-fragment.e2024.stderr b/tests/ui/macros/macro-missing-fragment.e2024.stderr new file mode 100644 index 00000000000..3afa069c170 --- /dev/null +++ b/tests/ui/macros/macro-missing-fragment.e2024.stderr @@ -0,0 +1,47 @@ +error: missing fragment specifier + --> $DIR/macro-missing-fragment.rs:9:20 + | +LL | ( $( any_token $field_rust_type )* ) => {}; + | ^^^^^^^^^^^^^^^^ + | + = note: fragment specifiers must be specified in the 2024 edition + = help: valid fragment specifiers are `ident`, `block`, `stmt`, `expr`, `expr_2021`, `pat`, `ty`, `lifetime`, `literal`, `path`, `meta`, `tt`, `item` and `vis` +help: try adding a specifier here + | +LL | ( $( any_token $field_rust_type:spec )* ) => {}; + | +++++ + +error: missing fragment specifier + --> $DIR/macro-missing-fragment.rs:19:7 + | +LL | ( $name ) => {}; + | ^^^^^ + | + = note: fragment specifiers must be specified in the 2024 edition + = help: valid fragment specifiers are `ident`, `block`, `stmt`, `expr`, `expr_2021`, `pat`, `ty`, `lifetime`, `literal`, `path`, `meta`, `tt`, `item` and `vis` +help: try adding a specifier here + | +LL | ( $name:spec ) => {}; + | +++++ + +error: missing fragment specifier + --> $DIR/macro-missing-fragment.rs:26:7 + | +LL | ( $name ) => {}; + | ^^^^^ + | + = note: fragment specifiers must be specified in the 2024 edition + = help: valid fragment specifiers are `ident`, `block`, `stmt`, `expr`, `expr_2021`, `pat`, `ty`, `lifetime`, `literal`, `path`, `meta`, `tt`, `item` and `vis` +help: try adding a specifier here + | +LL | ( $name:spec ) => {}; + | +++++ + +error: missing fragment specifier + --> $DIR/macro-missing-fragment.rs:9:20 + | +LL | ( $( any_token $field_rust_type )* ) => {}; + | ^^^^^^^^^^^^^^^^ + +error: aborting due to 4 previous errors + diff --git a/tests/ui/macros/macro-missing-fragment.rs b/tests/ui/macros/macro-missing-fragment.rs index 210c85ebbf2..b7da87ae610 100644 --- a/tests/ui/macros/macro-missing-fragment.rs +++ b/tests/ui/macros/macro-missing-fragment.rs @@ -1,23 +1,32 @@ +//@ revisions: e2015 e2024 +//@[e2015] edition:2015 +//@[e2024] edition:2024 +//@[e2024] compile-flags: -Zunstable-options + #![warn(missing_fragment_specifier)] macro_rules! used_arm { ( $( any_token $field_rust_type )* ) => {}; - //~^ ERROR missing fragment - //~| WARN missing fragment - //~| WARN this was previously accepted + //[e2015]~^ ERROR missing fragment + //[e2015]~| WARN missing fragment + //[e2015]~| WARN this was previously accepted + //[e2024]~^^^^ ERROR missing fragment + //[e2024]~| ERROR missing fragment } macro_rules! used_macro_unused_arm { () => {}; ( $name ) => {}; - //~^ WARN missing fragment - //~| WARN this was previously accepted + //[e2015]~^ WARN missing fragment + //[e2015]~| WARN this was previously accepted + //[e2024]~^^^ ERROR missing fragment } macro_rules! unused_macro { ( $name ) => {}; - //~^ WARN missing fragment - //~| WARN this was previously accepted + //[e2015]~^ WARN missing fragment + //[e2015]~| WARN this was previously accepted + //[e2024]~^^^ ERROR missing fragment } fn main() { diff --git a/tests/ui/maybe-bounds.stderr b/tests/ui/maybe-bounds.stderr index 1d823b6acb2..230d11fd0ae 100644 --- a/tests/ui/maybe-bounds.stderr +++ b/tests/ui/maybe-bounds.stderr @@ -1,22 +1,31 @@ -error: `?Trait` is not permitted in supertraits +error[E0658]: `?Trait` is not permitted in supertraits --> $DIR/maybe-bounds.rs:1:11 | LL | trait Tr: ?Sized {} | ^^^^^^ | = note: traits are `?Sized` by default + = help: add `#![feature(more_maybe_bounds)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date -error: `?Trait` is not permitted in trait object types +error[E0658]: `?Trait` is not permitted in trait object types --> $DIR/maybe-bounds.rs:4:20 | LL | type A1 = dyn Tr + (?Sized); | ^^^^^^^^ + | + = help: add `#![feature(more_maybe_bounds)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date -error: `?Trait` is not permitted in trait object types +error[E0658]: `?Trait` is not permitted in trait object types --> $DIR/maybe-bounds.rs:6:28 | LL | type A2 = dyn for<'a> Tr + (?Sized); | ^^^^^^^^ + | + = help: add `#![feature(more_maybe_bounds)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error: aborting due to 3 previous errors +For more information about this error, try `rustc --explain E0658`. diff --git a/tests/ui/or-patterns/exhaustiveness-unreachable-pattern.rs b/tests/ui/or-patterns/exhaustiveness-unreachable-pattern.rs index 1ad335bf394..afdcff0346b 100644 --- a/tests/ui/or-patterns/exhaustiveness-unreachable-pattern.rs +++ b/tests/ui/or-patterns/exhaustiveness-unreachable-pattern.rs @@ -29,6 +29,11 @@ fn main() { (1, 4 | 5) => {} //~ ERROR unreachable pattern _ => {} } + match (0u8, 0u8, 0u8) { + (0, 0, 0) => {} + (0, 0 | 1, 0) => {} //~ ERROR unreachable pattern + _ => {} + } match (true, true) { (false | true, false | true) => (), } diff --git a/tests/ui/or-patterns/exhaustiveness-unreachable-pattern.stderr b/tests/ui/or-patterns/exhaustiveness-unreachable-pattern.stderr index 336530d1b32..5570390b21c 100644 --- a/tests/ui/or-patterns/exhaustiveness-unreachable-pattern.stderr +++ b/tests/ui/or-patterns/exhaustiveness-unreachable-pattern.stderr @@ -1,8 +1,10 @@ error: unreachable pattern --> $DIR/exhaustiveness-unreachable-pattern.rs:8:9 | +LL | (1 | 2,) => {} + | -------- matches all the values already LL | (1,) => {} - | ^^^^ + | ^^^^ unreachable pattern | note: the lint level is defined here --> $DIR/exhaustiveness-unreachable-pattern.rs:1:9 @@ -13,212 +15,354 @@ LL | #![deny(unreachable_patterns)] error: unreachable pattern --> $DIR/exhaustiveness-unreachable-pattern.rs:13:9 | +LL | (1 | 2,) => {} + | -------- matches all the values already LL | (2,) => {} - | ^^^^ + | ^^^^ unreachable pattern error: unreachable pattern --> $DIR/exhaustiveness-unreachable-pattern.rs:19:9 | LL | (1 | 2,) => {} - | ^^^^^^^^ + | ^^^^^^^^ unreachable pattern + | +note: these patterns collectively make the last one unreachable + --> $DIR/exhaustiveness-unreachable-pattern.rs:19:9 + | +LL | (1,) => {} + | ---- matches some of the same values +LL | (2,) => {} + | ---- matches some of the same values +LL | (1 | 2,) => {} + | ^^^^^^^^ collectively making this unreachable error: unreachable pattern --> $DIR/exhaustiveness-unreachable-pattern.rs:24:9 | +LL | (1 | 2, 3 | 4) => {} + | -------------- matches all the values already LL | (1, 3) => {} - | ^^^^^^ + | ^^^^^^ unreachable pattern error: unreachable pattern --> $DIR/exhaustiveness-unreachable-pattern.rs:25:9 | +LL | (1 | 2, 3 | 4) => {} + | -------------- matches all the values already +LL | (1, 3) => {} LL | (1, 4) => {} - | ^^^^^^ + | ^^^^^^ unreachable pattern error: unreachable pattern --> $DIR/exhaustiveness-unreachable-pattern.rs:26:9 | +LL | (1 | 2, 3 | 4) => {} + | -------------- matches all the values already +... LL | (2, 4) => {} - | ^^^^^^ + | ^^^^^^ unreachable pattern error: unreachable pattern --> $DIR/exhaustiveness-unreachable-pattern.rs:27:9 | +LL | (1 | 2, 3 | 4) => {} + | -------------- matches all the values already +... LL | (2 | 1, 4) => {} - | ^^^^^^^^^^ + | ^^^^^^^^^^ unreachable pattern error: unreachable pattern --> $DIR/exhaustiveness-unreachable-pattern.rs:29:9 | LL | (1, 4 | 5) => {} - | ^^^^^^^^^^ + | ^^^^^^^^^^ unreachable pattern + | +note: these patterns collectively make the last one unreachable + --> $DIR/exhaustiveness-unreachable-pattern.rs:29:9 + | +LL | (1 | 2, 3 | 4) => {} + | -------------- matches some of the same values +... +LL | (1, 5 | 6) => {} + | ---------- matches some of the same values +LL | (1, 4 | 5) => {} + | ^^^^^^^^^^ collectively making this unreachable error: unreachable pattern - --> $DIR/exhaustiveness-unreachable-pattern.rs:37:9 + --> $DIR/exhaustiveness-unreachable-pattern.rs:34:13 | +LL | (0, 0, 0) => {} + | - matches all the values already +LL | (0, 0 | 1, 0) => {} + | ^ unreachable pattern + +error: unreachable pattern + --> $DIR/exhaustiveness-unreachable-pattern.rs:42:9 + | +LL | (None | Some(1 | 2),) => {} + | --------------------- matches all the values already LL | (Some(1),) => {} - | ^^^^^^^^^^ + | ^^^^^^^^^^ unreachable pattern error: unreachable pattern - --> $DIR/exhaustiveness-unreachable-pattern.rs:38:9 + --> $DIR/exhaustiveness-unreachable-pattern.rs:43:9 | +LL | (None | Some(1 | 2),) => {} + | --------------------- matches all the values already +LL | (Some(1),) => {} LL | (None,) => {} - | ^^^^^^^ + | ^^^^^^^ unreachable pattern error: unreachable pattern - --> $DIR/exhaustiveness-unreachable-pattern.rs:43:9 + --> $DIR/exhaustiveness-unreachable-pattern.rs:48:9 | +LL | ((1 | 2,) | (3 | 4,),) => {} + | ---------------------- matches all the values already LL | ((1..=4,),) => {} - | ^^^^^^^^^^^ + | ^^^^^^^^^^^ unreachable pattern error: unreachable pattern - --> $DIR/exhaustiveness-unreachable-pattern.rs:48:14 + --> $DIR/exhaustiveness-unreachable-pattern.rs:53:14 | LL | (1 | 1,) => {} - | ^ + | - ^ unreachable pattern + | | + | matches all the values already error: unreachable pattern - --> $DIR/exhaustiveness-unreachable-pattern.rs:52:19 + --> $DIR/exhaustiveness-unreachable-pattern.rs:57:19 | LL | (0 | 1) | 1 => {} - | ^ + | - ^ unreachable pattern + | | + | matches all the values already error: unreachable pattern - --> $DIR/exhaustiveness-unreachable-pattern.rs:58:14 + --> $DIR/exhaustiveness-unreachable-pattern.rs:63:14 | LL | 0 | (0 | 0) => {} - | ^ + | - ^ unreachable pattern + | | + | matches all the values already error: unreachable pattern - --> $DIR/exhaustiveness-unreachable-pattern.rs:58:18 + --> $DIR/exhaustiveness-unreachable-pattern.rs:63:18 | LL | 0 | (0 | 0) => {} - | ^ + | - ^ unreachable pattern + | | + | matches all the values already error: unreachable pattern - --> $DIR/exhaustiveness-unreachable-pattern.rs:66:13 + --> $DIR/exhaustiveness-unreachable-pattern.rs:71:13 | +LL | Some(0) | + | ------- matches all the values already LL | / Some( LL | | 0 | 0) => {} - | |______________________^ + | |______________________^ unreachable pattern error: unreachable pattern - --> $DIR/exhaustiveness-unreachable-pattern.rs:72:15 + --> $DIR/exhaustiveness-unreachable-pattern.rs:77:15 | +LL | [0 + | - matches all the values already LL | | 0 - | ^ + | ^ unreachable pattern error: unreachable pattern - --> $DIR/exhaustiveness-unreachable-pattern.rs:74:15 + --> $DIR/exhaustiveness-unreachable-pattern.rs:79:15 | +LL | , 0 + | - matches all the values already LL | | 0] => {} - | ^ + | ^ unreachable pattern error: unreachable pattern - --> $DIR/exhaustiveness-unreachable-pattern.rs:78:20 + --> $DIR/exhaustiveness-unreachable-pattern.rs:83:20 | LL | (true, 0 | 0) => {} - | ^ + | - ^ unreachable pattern + | | + | matches all the values already error: unreachable pattern - --> $DIR/exhaustiveness-unreachable-pattern.rs:79:17 + --> $DIR/exhaustiveness-unreachable-pattern.rs:84:17 | LL | (_, 0 | 0) => {} - | ^ + | ^ unreachable pattern + | +note: these patterns collectively make the last one unreachable + --> $DIR/exhaustiveness-unreachable-pattern.rs:84:17 + | +LL | (true, 0 | 0) => {} + | - matches some of the same values +LL | (_, 0 | 0) => {} + | - ^ collectively making this unreachable + | | + | matches some of the same values error: unreachable pattern - --> $DIR/exhaustiveness-unreachable-pattern.rs:87:10 + --> $DIR/exhaustiveness-unreachable-pattern.rs:92:10 | +LL | [1, ..] => {} + | - matches all the values already LL | [1 - | ^ + | ^ unreachable pattern error: unreachable pattern - --> $DIR/exhaustiveness-unreachable-pattern.rs:99:10 + --> $DIR/exhaustiveness-unreachable-pattern.rs:104:10 | +LL | [true, ..] => {} + | ---- matches all the values already LL | [true - | ^^^^ + | ^^^^ unreachable pattern error: unreachable pattern - --> $DIR/exhaustiveness-unreachable-pattern.rs:106:36 + --> $DIR/exhaustiveness-unreachable-pattern.rs:111:36 | LL | (true | false, None | Some(true - | ^^^^ + | ^^^^ unreachable pattern + | +note: these patterns collectively make the last one unreachable + --> $DIR/exhaustiveness-unreachable-pattern.rs:111:36 + | +LL | (true, Some(_)) => {} + | - matches some of the same values +LL | (false, Some(true)) => {} + | ---- matches some of the same values +LL | (true | false, None | Some(true + | ^^^^ collectively making this unreachable error: unreachable pattern - --> $DIR/exhaustiveness-unreachable-pattern.rs:111:14 + --> $DIR/exhaustiveness-unreachable-pattern.rs:116:14 | LL | (true - | ^^^^ + | ^^^^ unreachable pattern ... LL | (true | false, None | Some(t_or_f!())) => {} | --------- in this macro invocation | +note: these patterns collectively make the last one unreachable + --> $DIR/exhaustiveness-unreachable-pattern.rs:116:14 + | +LL | (true + | ^^^^ collectively making this unreachable +... +LL | (true, Some(_)) => {} + | - matches some of the same values +LL | (false, Some(true)) => {} + | ---- matches some of the same values +LL | (true | false, None | Some(t_or_f!())) => {} + | --------- in this macro invocation = note: this error originates in the macro `t_or_f` (in Nightly builds, run with -Z macro-backtrace for more info) error: unreachable pattern - --> $DIR/exhaustiveness-unreachable-pattern.rs:122:14 + --> $DIR/exhaustiveness-unreachable-pattern.rs:127:14 | +LL | Some(0) => {} + | - matches all the values already LL | Some(0 - | ^ + | ^ unreachable pattern error: unreachable pattern - --> $DIR/exhaustiveness-unreachable-pattern.rs:141:19 + --> $DIR/exhaustiveness-unreachable-pattern.rs:146:19 | +LL | Some(false) => {} + | ----- matches all the values already +LL | None | Some(true LL | | false) => {} - | ^^^^^ + | ^^^^^ unreachable pattern error: unreachable pattern - --> $DIR/exhaustiveness-unreachable-pattern.rs:149:15 + --> $DIR/exhaustiveness-unreachable-pattern.rs:154:15 | LL | | true) => {} - | ^^^^ + | ^^^^ unreachable pattern + | +note: these patterns collectively make the last one unreachable + --> $DIR/exhaustiveness-unreachable-pattern.rs:154:15 + | +LL | (false, true) => {} + | ---- matches some of the same values +LL | (true, true) => {} + | ---- matches some of the same values +LL | (false | true, false +LL | | true) => {} + | ^^^^ collectively making this unreachable error: unreachable pattern - --> $DIR/exhaustiveness-unreachable-pattern.rs:155:15 + --> $DIR/exhaustiveness-unreachable-pattern.rs:160:15 | LL | | true, - | ^^^^ + | ^^^^ unreachable pattern + | +note: these patterns collectively make the last one unreachable + --> $DIR/exhaustiveness-unreachable-pattern.rs:160:15 + | +LL | (true, false) => {} + | ---- matches some of the same values +LL | (true, true) => {} + | ---- matches some of the same values +LL | (false +LL | | true, + | ^^^^ collectively making this unreachable error: unreachable pattern - --> $DIR/exhaustiveness-unreachable-pattern.rs:160:15 + --> $DIR/exhaustiveness-unreachable-pattern.rs:165:15 | +LL | (x, y) + | ------ matches any value LL | | (y, x) => {} - | ^^^^^^ + | ^^^^^^ unreachable pattern error: unreachable pattern - --> $DIR/exhaustiveness-unreachable-pattern.rs:164:30 + --> $DIR/exhaustiveness-unreachable-pattern.rs:169:30 | LL | fn unreachable_in_param((_ | (_, _)): (bool, bool)) {} - | ^^^^^^ + | - ^^^^^^ unreachable pattern + | | + | matches any value error: unreachable pattern - --> $DIR/exhaustiveness-unreachable-pattern.rs:171:14 + --> $DIR/exhaustiveness-unreachable-pattern.rs:176:14 | LL | let (_ | (_, _)) = bool_pair; - | ^^^^^^ + | - ^^^^^^ unreachable pattern + | | + | matches any value error: unreachable pattern - --> $DIR/exhaustiveness-unreachable-pattern.rs:173:14 + --> $DIR/exhaustiveness-unreachable-pattern.rs:178:14 | LL | for (_ | (_, _)) in [bool_pair] {} - | ^^^^^^ + | - ^^^^^^ unreachable pattern + | | + | matches any value error: unreachable pattern - --> $DIR/exhaustiveness-unreachable-pattern.rs:176:20 + --> $DIR/exhaustiveness-unreachable-pattern.rs:181:20 | LL | let (Some(_) | Some(true)) = bool_option else { return }; - | ^^^^^^^^^^ + | ------- ^^^^^^^^^^ unreachable pattern + | | + | matches all the values already error: unreachable pattern - --> $DIR/exhaustiveness-unreachable-pattern.rs:178:22 + --> $DIR/exhaustiveness-unreachable-pattern.rs:183:22 | LL | if let Some(_) | Some(true) = bool_option {} - | ^^^^^^^^^^ + | ------- ^^^^^^^^^^ unreachable pattern + | | + | matches all the values already error: unreachable pattern - --> $DIR/exhaustiveness-unreachable-pattern.rs:180:25 + --> $DIR/exhaustiveness-unreachable-pattern.rs:185:25 | LL | while let Some(_) | Some(true) = bool_option {} - | ^^^^^^^^^^ + | ------- ^^^^^^^^^^ unreachable pattern + | | + | matches all the values already -error: aborting due to 35 previous errors +error: aborting due to 36 previous errors diff --git a/tests/ui/parser/issues/issue-19398.rs b/tests/ui/parser/issues/issue-19398.rs index 46eb320a172..358f65f1da5 100644 --- a/tests/ui/parser/issues/issue-19398.rs +++ b/tests/ui/parser/issues/issue-19398.rs @@ -1,6 +1,10 @@ trait T { extern "Rust" unsafe fn foo(); - //~^ ERROR expected `{`, found keyword `unsafe` + //~^ ERROR expected `fn`, found keyword `unsafe` + //~| NOTE expected `fn` + //~| HELP `unsafe` must come before `extern "Rust"` + //~| SUGGESTION unsafe extern "Rust" + //~| NOTE keyword order for functions declaration is `pub`, `default`, `const`, `async`, `unsafe`, `extern` } fn main() {} diff --git a/tests/ui/parser/issues/issue-19398.stderr b/tests/ui/parser/issues/issue-19398.stderr index 236fac673b6..2b97ec50c91 100644 --- a/tests/ui/parser/issues/issue-19398.stderr +++ b/tests/ui/parser/issues/issue-19398.stderr @@ -1,13 +1,13 @@ -error: expected `{`, found keyword `unsafe` +error: expected `fn`, found keyword `unsafe` --> $DIR/issue-19398.rs:2:19 | -LL | trait T { - | - while parsing this item list starting here LL | extern "Rust" unsafe fn foo(); - | ^^^^^^ expected `{` -LL | -LL | } - | - the item list ends here + | --------------^^^^^^ + | | | + | | expected `fn` + | help: `unsafe` must come before `extern "Rust"`: `unsafe extern "Rust"` + | + = note: keyword order for functions declaration is `pub`, `default`, `const`, `async`, `unsafe`, `extern` error: aborting due to 1 previous error diff --git a/tests/ui/parser/issues/issue-87217-keyword-order/wrong-unsafe-abi.rs b/tests/ui/parser/issues/issue-87217-keyword-order/wrong-unsafe-abi.rs new file mode 100644 index 00000000000..794ac635c76 --- /dev/null +++ b/tests/ui/parser/issues/issue-87217-keyword-order/wrong-unsafe-abi.rs @@ -0,0 +1,16 @@ +//@ edition:2018 + +// There is an order to respect for keywords before a function: +// `<visibility>, const, async, unsafe, extern, "<ABI>"` +// +// This test ensures the compiler is helpful about them being misplaced. +// Visibilities are tested elsewhere. + +extern "C" unsafe fn test() {} +//~^ ERROR expected `fn`, found keyword `unsafe` +//~| NOTE expected `fn` +//~| HELP `unsafe` must come before `extern "C"` +//~| SUGGESTION unsafe extern "C" +//~| NOTE keyword order for functions declaration is `pub`, `default`, `const`, `async`, `unsafe`, `extern` + +fn main() {} diff --git a/tests/ui/parser/issues/issue-87217-keyword-order/wrong-unsafe-abi.stderr b/tests/ui/parser/issues/issue-87217-keyword-order/wrong-unsafe-abi.stderr new file mode 100644 index 00000000000..8ed037869c8 --- /dev/null +++ b/tests/ui/parser/issues/issue-87217-keyword-order/wrong-unsafe-abi.stderr @@ -0,0 +1,13 @@ +error: expected `fn`, found keyword `unsafe` + --> $DIR/wrong-unsafe-abi.rs:9:12 + | +LL | extern "C" unsafe fn test() {} + | -----------^^^^^^ + | | | + | | expected `fn` + | help: `unsafe` must come before `extern "C"`: `unsafe extern "C"` + | + = note: keyword order for functions declaration is `pub`, `default`, `const`, `async`, `unsafe`, `extern` + +error: aborting due to 1 previous error + diff --git a/tests/ui/parser/trait-object-trait-parens.stderr b/tests/ui/parser/trait-object-trait-parens.stderr index 3134746b930..ff32b173d49 100644 --- a/tests/ui/parser/trait-object-trait-parens.stderr +++ b/tests/ui/parser/trait-object-trait-parens.stderr @@ -1,20 +1,29 @@ -error: `?Trait` is not permitted in trait object types +error[E0658]: `?Trait` is not permitted in trait object types --> $DIR/trait-object-trait-parens.rs:8:24 | LL | let _: Box<(Obj) + (?Sized) + (for<'a> Trait<'a>)>; | ^^^^^^^^ + | + = help: add `#![feature(more_maybe_bounds)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date -error: `?Trait` is not permitted in trait object types +error[E0658]: `?Trait` is not permitted in trait object types --> $DIR/trait-object-trait-parens.rs:13:16 | LL | let _: Box<?Sized + (for<'a> Trait<'a>) + (Obj)>; | ^^^^^^ + | + = help: add `#![feature(more_maybe_bounds)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date -error: `?Trait` is not permitted in trait object types +error[E0658]: `?Trait` is not permitted in trait object types --> $DIR/trait-object-trait-parens.rs:18:44 | LL | let _: Box<for<'a> Trait<'a> + (Obj) + (?Sized)>; | ^^^^^^^^ + | + = help: add `#![feature(more_maybe_bounds)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date warning: trait objects without an explicit `dyn` are deprecated --> $DIR/trait-object-trait-parens.rs:8:16 @@ -91,4 +100,5 @@ LL | let _: Box<for<'a> Trait<'a> + (Obj) + (?Sized)>; error: aborting due to 6 previous errors; 3 warnings emitted -For more information about this error, try `rustc --explain E0225`. +Some errors have detailed explanations: E0225, E0658. +For more information about an error, try `rustc --explain E0225`. diff --git a/tests/ui/pattern/usefulness/consts-opaque.stderr b/tests/ui/pattern/usefulness/consts-opaque.stderr index d057309e420..9d3a35321ca 100644 --- a/tests/ui/pattern/usefulness/consts-opaque.stderr +++ b/tests/ui/pattern/usefulness/consts-opaque.stderr @@ -106,20 +106,34 @@ LL | _ => {} // should not be emitting unreachable warning error: unreachable pattern --> $DIR/consts-opaque.rs:72:9 | +LL | BAZ => {} + | --- matches all the values already LL | Baz::Baz1 => {} // should not be emitting unreachable warning - | ^^^^^^^^^ + | ^^^^^^^^^ unreachable pattern error: unreachable pattern --> $DIR/consts-opaque.rs:79:9 | +LL | Baz::Baz1 => {} + | --------- matches all the values already LL | BAZ => {} - | ^^^ + | ^^^ unreachable pattern error: unreachable pattern --> $DIR/consts-opaque.rs:87:9 | LL | _ => {} // should not be emitting unreachable warning - | ^ + | ^ unreachable pattern + | +note: these patterns collectively make the last one unreachable + --> $DIR/consts-opaque.rs:87:9 + | +LL | BAZ => {} + | --- matches some of the same values +LL | Baz::Baz2 => {} + | --------- matches some of the same values +LL | _ => {} // should not be emitting unreachable warning + | ^ collectively making this unreachable error: aborting due to 17 previous errors diff --git a/tests/ui/pattern/usefulness/empty-match-check-notes.exhaustive_patterns.stderr b/tests/ui/pattern/usefulness/empty-match-check-notes.exhaustive_patterns.stderr index 4c434192431..9e700ee55ef 100644 --- a/tests/ui/pattern/usefulness/empty-match-check-notes.exhaustive_patterns.stderr +++ b/tests/ui/pattern/usefulness/empty-match-check-notes.exhaustive_patterns.stderr @@ -4,6 +4,7 @@ error: unreachable pattern LL | _ => {} | ^ | + = note: this pattern matches no values because `EmptyEnum` is uninhabited note: the lint level is defined here --> $DIR/empty-match-check-notes.rs:7:9 | @@ -11,25 +12,31 @@ LL | #![deny(unreachable_patterns)] | ^^^^^^^^^^^^^^^^^^^^ error: unreachable pattern - --> $DIR/empty-match-check-notes.rs:20:9 + --> $DIR/empty-match-check-notes.rs:21:9 | LL | _ if false => {} | ^ + | + = note: this pattern matches no values because `EmptyEnum` is uninhabited error: unreachable pattern - --> $DIR/empty-match-check-notes.rs:27:9 + --> $DIR/empty-match-check-notes.rs:29:9 | LL | _ => {} | ^ + | + = note: this pattern matches no values because `EmptyForeignEnum` is uninhabited error: unreachable pattern - --> $DIR/empty-match-check-notes.rs:30:9 + --> $DIR/empty-match-check-notes.rs:33:9 | LL | _ if false => {} | ^ + | + = note: this pattern matches no values because `EmptyForeignEnum` is uninhabited error[E0005]: refutable pattern in local binding - --> $DIR/empty-match-check-notes.rs:35:9 + --> $DIR/empty-match-check-notes.rs:39:9 | LL | let None = x; | ^^^^ pattern `Some(_)` not covered @@ -44,7 +51,7 @@ LL | if let None = x { todo!() }; | ++ +++++++++++ error[E0004]: non-exhaustive patterns: `0_u8..=u8::MAX` not covered - --> $DIR/empty-match-check-notes.rs:45:11 + --> $DIR/empty-match-check-notes.rs:49:11 | LL | match 0u8 { | ^^^ pattern `0_u8..=u8::MAX` not covered diff --git a/tests/ui/pattern/usefulness/empty-match-check-notes.normal.stderr b/tests/ui/pattern/usefulness/empty-match-check-notes.normal.stderr index 45f715dc7b2..480ae7095a6 100644 --- a/tests/ui/pattern/usefulness/empty-match-check-notes.normal.stderr +++ b/tests/ui/pattern/usefulness/empty-match-check-notes.normal.stderr @@ -4,6 +4,7 @@ error: unreachable pattern LL | _ => {} | ^ | + = note: this pattern matches no values because `EmptyEnum` is uninhabited note: the lint level is defined here --> $DIR/empty-match-check-notes.rs:7:9 | @@ -11,25 +12,31 @@ LL | #![deny(unreachable_patterns)] | ^^^^^^^^^^^^^^^^^^^^ error: unreachable pattern - --> $DIR/empty-match-check-notes.rs:20:9 + --> $DIR/empty-match-check-notes.rs:21:9 | LL | _ if false => {} | ^ + | + = note: this pattern matches no values because `EmptyEnum` is uninhabited error: unreachable pattern - --> $DIR/empty-match-check-notes.rs:27:9 + --> $DIR/empty-match-check-notes.rs:29:9 | LL | _ => {} | ^ + | + = note: this pattern matches no values because `EmptyForeignEnum` is uninhabited error: unreachable pattern - --> $DIR/empty-match-check-notes.rs:30:9 + --> $DIR/empty-match-check-notes.rs:33:9 | LL | _ if false => {} | ^ + | + = note: this pattern matches no values because `EmptyForeignEnum` is uninhabited error[E0005]: refutable pattern in local binding - --> $DIR/empty-match-check-notes.rs:35:9 + --> $DIR/empty-match-check-notes.rs:39:9 | LL | let None = x; | ^^^^ pattern `Some(_)` not covered @@ -43,7 +50,7 @@ LL | if let None = x { todo!() }; | ++ +++++++++++ error[E0004]: non-exhaustive patterns: `0_u8..=u8::MAX` not covered - --> $DIR/empty-match-check-notes.rs:45:11 + --> $DIR/empty-match-check-notes.rs:49:11 | LL | match 0u8 { | ^^^ pattern `0_u8..=u8::MAX` not covered diff --git a/tests/ui/pattern/usefulness/empty-match-check-notes.rs b/tests/ui/pattern/usefulness/empty-match-check-notes.rs index ea797bc7dd5..2eef283a21e 100644 --- a/tests/ui/pattern/usefulness/empty-match-check-notes.rs +++ b/tests/ui/pattern/usefulness/empty-match-check-notes.rs @@ -15,9 +15,11 @@ fn empty_enum(x: EmptyEnum) { match x {} // ok match x { _ => {} //~ ERROR unreachable pattern + //~^ NOTE matches no values } match x { _ if false => {} //~ ERROR unreachable pattern + //~^ NOTE matches no values } } @@ -25,9 +27,11 @@ fn empty_foreign_enum(x: empty::EmptyForeignEnum) { match x {} // ok match x { _ => {} //~ ERROR unreachable pattern + //~^ NOTE matches no values } match x { _ if false => {} //~ ERROR unreachable pattern + //~^ NOTE matches no values } } diff --git a/tests/ui/pattern/usefulness/empty-types.exhaustive_patterns.stderr b/tests/ui/pattern/usefulness/empty-types.exhaustive_patterns.stderr index 45bdba94d78..416a50b87b5 100644 --- a/tests/ui/pattern/usefulness/empty-types.exhaustive_patterns.stderr +++ b/tests/ui/pattern/usefulness/empty-types.exhaustive_patterns.stderr @@ -4,6 +4,7 @@ error: unreachable pattern LL | _ => {} | ^ | + = note: this pattern matches no values because `!` is uninhabited note: the lint level is defined here --> $DIR/empty-types.rs:17:9 | @@ -15,6 +16,8 @@ error: unreachable pattern | LL | _x => {} | ^^ + | + = note: this pattern matches no values because `!` is uninhabited error[E0004]: non-exhaustive patterns: type `&!` is non-empty --> $DIR/empty-types.rs:58:11 @@ -36,24 +39,32 @@ error: unreachable pattern | LL | (_, _) => {} | ^^^^^^ + | + = note: this pattern matches no values because `(u32, !)` is uninhabited error: unreachable pattern --> $DIR/empty-types.rs:80:9 | LL | _ => {} | ^ + | + = note: this pattern matches no values because `(!, !)` is uninhabited error: unreachable pattern --> $DIR/empty-types.rs:83:9 | LL | (_, _) => {} | ^^^^^^ + | + = note: this pattern matches no values because `(!, !)` is uninhabited error: unreachable pattern --> $DIR/empty-types.rs:87:9 | LL | _ => {} | ^ + | + = note: this pattern matches no values because `!` is uninhabited error[E0004]: non-exhaustive patterns: `Ok(_)` not covered --> $DIR/empty-types.rs:91:11 @@ -79,12 +90,16 @@ error: unreachable pattern | LL | Err(_) => {} | ^^^^^^ + | + = note: this pattern matches no values because `!` is uninhabited error: unreachable pattern --> $DIR/empty-types.rs:104:9 | LL | Err(_) => {} | ^^^^^^ + | + = note: this pattern matches no values because `!` is uninhabited error[E0004]: non-exhaustive patterns: `Ok(1_u32..=u32::MAX)` not covered --> $DIR/empty-types.rs:101:11 @@ -123,114 +138,152 @@ error: unreachable pattern | LL | _ => {} | ^ + | + = note: this pattern matches no values because `Result<!, !>` is uninhabited error: unreachable pattern --> $DIR/empty-types.rs:123:9 | LL | Ok(_) => {} | ^^^^^ + | + = note: this pattern matches no values because `Result<!, !>` is uninhabited error: unreachable pattern --> $DIR/empty-types.rs:126:9 | LL | Ok(_) => {} | ^^^^^ + | + = note: this pattern matches no values because `Result<!, !>` is uninhabited error: unreachable pattern --> $DIR/empty-types.rs:127:9 | LL | _ => {} | ^ + | + = note: this pattern matches no values because `Result<!, !>` is uninhabited error: unreachable pattern --> $DIR/empty-types.rs:130:9 | LL | Ok(_) => {} | ^^^^^ + | + = note: this pattern matches no values because `Result<!, !>` is uninhabited error: unreachable pattern --> $DIR/empty-types.rs:131:9 | LL | Err(_) => {} | ^^^^^^ + | + = note: this pattern matches no values because `Result<!, !>` is uninhabited error: unreachable pattern --> $DIR/empty-types.rs:140:13 | LL | _ => {} | ^ + | + = note: this pattern matches no values because `Void` is uninhabited error: unreachable pattern --> $DIR/empty-types.rs:143:13 | LL | _ if false => {} | ^ + | + = note: this pattern matches no values because `Void` is uninhabited error: unreachable pattern --> $DIR/empty-types.rs:152:13 | LL | Some(_) => {} | ^^^^^^^ + | + = note: this pattern matches no values because `Void` is uninhabited error: unreachable pattern --> $DIR/empty-types.rs:156:13 | +LL | None => {} + | ---- matches all the values already LL | _ => {} - | ^ + | ^ unreachable pattern error: unreachable pattern --> $DIR/empty-types.rs:208:13 | LL | _ => {} | ^ + | + = note: this pattern matches no values because `!` is uninhabited error: unreachable pattern --> $DIR/empty-types.rs:213:13 | LL | _ => {} | ^ + | + = note: this pattern matches no values because `!` is uninhabited error: unreachable pattern --> $DIR/empty-types.rs:218:13 | LL | _ => {} | ^ + | + = note: this pattern matches no values because `!` is uninhabited error: unreachable pattern --> $DIR/empty-types.rs:223:13 | LL | _ => {} | ^ + | + = note: this pattern matches no values because `!` is uninhabited error: unreachable pattern --> $DIR/empty-types.rs:229:13 | LL | _ => {} | ^ + | + = note: this pattern matches no values because `!` is uninhabited error: unreachable pattern --> $DIR/empty-types.rs:288:9 | LL | _ => {} | ^ + | + = note: this pattern matches no values because `!` is uninhabited error: unreachable pattern --> $DIR/empty-types.rs:291:9 | LL | (_, _) => {} | ^^^^^^ + | + = note: this pattern matches no values because `(!, !)` is uninhabited error: unreachable pattern --> $DIR/empty-types.rs:294:9 | LL | Ok(_) => {} | ^^^^^ + | + = note: this pattern matches no values because `Result<!, !>` is uninhabited error: unreachable pattern --> $DIR/empty-types.rs:295:9 | LL | Err(_) => {} | ^^^^^^ + | + = note: this pattern matches no values because `Result<!, !>` is uninhabited error[E0004]: non-exhaustive patterns: type `&[!]` is non-empty --> $DIR/empty-types.rs:327:11 @@ -292,18 +345,24 @@ error: unreachable pattern | LL | _ => {} | ^ + | + = note: this pattern matches no values because `[!; 3]` is uninhabited error: unreachable pattern --> $DIR/empty-types.rs:372:9 | LL | [_, _, _] => {} | ^^^^^^^^^ + | + = note: this pattern matches no values because `[!; 3]` is uninhabited error: unreachable pattern --> $DIR/empty-types.rs:375:9 | LL | [_, ..] => {} | ^^^^^^^ + | + = note: this pattern matches no values because `[!; 3]` is uninhabited error[E0004]: non-exhaustive patterns: type `[!; 0]` is non-empty --> $DIR/empty-types.rs:389:11 @@ -322,8 +381,10 @@ LL + } error: unreachable pattern --> $DIR/empty-types.rs:396:9 | +LL | [] => {} + | -- matches all the values already LL | _ => {} - | ^ + | ^ unreachable pattern error[E0004]: non-exhaustive patterns: `[]` not covered --> $DIR/empty-types.rs:398:11 @@ -344,48 +405,66 @@ error: unreachable pattern | LL | Some(_) => {} | ^^^^^^^ + | + = note: this pattern matches no values because `!` is uninhabited error: unreachable pattern --> $DIR/empty-types.rs:422:9 | LL | Some(_a) => {} | ^^^^^^^^ + | + = note: this pattern matches no values because `!` is uninhabited error: unreachable pattern --> $DIR/empty-types.rs:427:9 | +LL | None => {} + | ---- matches all the values already +LL | // !useful, !reachable LL | _ => {} - | ^ + | ^ unreachable pattern error: unreachable pattern --> $DIR/empty-types.rs:432:9 | +LL | None => {} + | ---- matches all the values already +LL | // !useful, !reachable LL | _a => {} - | ^^ + | ^^ unreachable pattern error: unreachable pattern --> $DIR/empty-types.rs:604:9 | LL | _ => {} | ^ + | + = note: this pattern matches no values because `!` is uninhabited error: unreachable pattern --> $DIR/empty-types.rs:607:9 | LL | _x => {} | ^^ + | + = note: this pattern matches no values because `!` is uninhabited error: unreachable pattern --> $DIR/empty-types.rs:610:9 | LL | _ if false => {} | ^ + | + = note: this pattern matches no values because `!` is uninhabited error: unreachable pattern --> $DIR/empty-types.rs:613:9 | LL | _x if false => {} | ^^ + | + = note: this pattern matches no values because `!` is uninhabited error: aborting due to 49 previous errors diff --git a/tests/ui/pattern/usefulness/empty-types.min_exh_pats.stderr b/tests/ui/pattern/usefulness/empty-types.min_exh_pats.stderr index 9b57c895eea..2e5511527d5 100644 --- a/tests/ui/pattern/usefulness/empty-types.min_exh_pats.stderr +++ b/tests/ui/pattern/usefulness/empty-types.min_exh_pats.stderr @@ -4,6 +4,7 @@ error: unreachable pattern LL | _ => {} | ^ | + = note: this pattern matches no values because `!` is uninhabited note: the lint level is defined here --> $DIR/empty-types.rs:17:9 | @@ -15,6 +16,8 @@ error: unreachable pattern | LL | _x => {} | ^^ + | + = note: this pattern matches no values because `!` is uninhabited error[E0004]: non-exhaustive patterns: type `&!` is non-empty --> $DIR/empty-types.rs:58:11 @@ -36,24 +39,32 @@ error: unreachable pattern | LL | (_, _) => {} | ^^^^^^ + | + = note: this pattern matches no values because `(u32, !)` is uninhabited error: unreachable pattern --> $DIR/empty-types.rs:80:9 | LL | _ => {} | ^ + | + = note: this pattern matches no values because `(!, !)` is uninhabited error: unreachable pattern --> $DIR/empty-types.rs:83:9 | LL | (_, _) => {} | ^^^^^^ + | + = note: this pattern matches no values because `(!, !)` is uninhabited error: unreachable pattern --> $DIR/empty-types.rs:87:9 | LL | _ => {} | ^ + | + = note: this pattern matches no values because `!` is uninhabited error[E0004]: non-exhaustive patterns: `Ok(_)` not covered --> $DIR/empty-types.rs:91:11 @@ -79,12 +90,16 @@ error: unreachable pattern | LL | Err(_) => {} | ^^^^^^ + | + = note: this pattern matches no values because `!` is uninhabited error: unreachable pattern --> $DIR/empty-types.rs:104:9 | LL | Err(_) => {} | ^^^^^^ + | + = note: this pattern matches no values because `!` is uninhabited error[E0004]: non-exhaustive patterns: `Ok(1_u32..=u32::MAX)` not covered --> $DIR/empty-types.rs:101:11 @@ -137,60 +152,80 @@ error: unreachable pattern | LL | _ => {} | ^ + | + = note: this pattern matches no values because `Result<!, !>` is uninhabited error: unreachable pattern --> $DIR/empty-types.rs:123:9 | LL | Ok(_) => {} | ^^^^^ + | + = note: this pattern matches no values because `Result<!, !>` is uninhabited error: unreachable pattern --> $DIR/empty-types.rs:126:9 | LL | Ok(_) => {} | ^^^^^ + | + = note: this pattern matches no values because `Result<!, !>` is uninhabited error: unreachable pattern --> $DIR/empty-types.rs:127:9 | LL | _ => {} | ^ + | + = note: this pattern matches no values because `Result<!, !>` is uninhabited error: unreachable pattern --> $DIR/empty-types.rs:130:9 | LL | Ok(_) => {} | ^^^^^ + | + = note: this pattern matches no values because `Result<!, !>` is uninhabited error: unreachable pattern --> $DIR/empty-types.rs:131:9 | LL | Err(_) => {} | ^^^^^^ + | + = note: this pattern matches no values because `Result<!, !>` is uninhabited error: unreachable pattern --> $DIR/empty-types.rs:140:13 | LL | _ => {} | ^ + | + = note: this pattern matches no values because `Void` is uninhabited error: unreachable pattern --> $DIR/empty-types.rs:143:13 | LL | _ if false => {} | ^ + | + = note: this pattern matches no values because `Void` is uninhabited error: unreachable pattern --> $DIR/empty-types.rs:152:13 | LL | Some(_) => {} | ^^^^^^^ + | + = note: this pattern matches no values because `Void` is uninhabited error: unreachable pattern --> $DIR/empty-types.rs:156:13 | +LL | None => {} + | ---- matches all the values already LL | _ => {} - | ^ + | ^ unreachable pattern error[E0004]: non-exhaustive patterns: `Some(_)` not covered --> $DIR/empty-types.rs:165:15 @@ -216,54 +251,72 @@ error: unreachable pattern | LL | _ => {} | ^ + | + = note: this pattern matches no values because `!` is uninhabited error: unreachable pattern --> $DIR/empty-types.rs:213:13 | LL | _ => {} | ^ + | + = note: this pattern matches no values because `!` is uninhabited error: unreachable pattern --> $DIR/empty-types.rs:218:13 | LL | _ => {} | ^ + | + = note: this pattern matches no values because `!` is uninhabited error: unreachable pattern --> $DIR/empty-types.rs:223:13 | LL | _ => {} | ^ + | + = note: this pattern matches no values because `!` is uninhabited error: unreachable pattern --> $DIR/empty-types.rs:229:13 | LL | _ => {} | ^ + | + = note: this pattern matches no values because `!` is uninhabited error: unreachable pattern --> $DIR/empty-types.rs:288:9 | LL | _ => {} | ^ + | + = note: this pattern matches no values because `!` is uninhabited error: unreachable pattern --> $DIR/empty-types.rs:291:9 | LL | (_, _) => {} | ^^^^^^ + | + = note: this pattern matches no values because `(!, !)` is uninhabited error: unreachable pattern --> $DIR/empty-types.rs:294:9 | LL | Ok(_) => {} | ^^^^^ + | + = note: this pattern matches no values because `Result<!, !>` is uninhabited error: unreachable pattern --> $DIR/empty-types.rs:295:9 | LL | Err(_) => {} | ^^^^^^ + | + = note: this pattern matches no values because `Result<!, !>` is uninhabited error[E0004]: non-exhaustive patterns: type `(u32, !)` is non-empty --> $DIR/empty-types.rs:316:11 @@ -403,18 +456,24 @@ error: unreachable pattern | LL | _ => {} | ^ + | + = note: this pattern matches no values because `[!; 3]` is uninhabited error: unreachable pattern --> $DIR/empty-types.rs:372:9 | LL | [_, _, _] => {} | ^^^^^^^^^ + | + = note: this pattern matches no values because `[!; 3]` is uninhabited error: unreachable pattern --> $DIR/empty-types.rs:375:9 | LL | [_, ..] => {} | ^^^^^^^ + | + = note: this pattern matches no values because `[!; 3]` is uninhabited error[E0004]: non-exhaustive patterns: type `[!; 0]` is non-empty --> $DIR/empty-types.rs:389:11 @@ -433,8 +492,10 @@ LL + } error: unreachable pattern --> $DIR/empty-types.rs:396:9 | +LL | [] => {} + | -- matches all the values already LL | _ => {} - | ^ + | ^ unreachable pattern error[E0004]: non-exhaustive patterns: `[]` not covered --> $DIR/empty-types.rs:398:11 @@ -455,24 +516,34 @@ error: unreachable pattern | LL | Some(_) => {} | ^^^^^^^ + | + = note: this pattern matches no values because `!` is uninhabited error: unreachable pattern --> $DIR/empty-types.rs:422:9 | LL | Some(_a) => {} | ^^^^^^^^ + | + = note: this pattern matches no values because `!` is uninhabited error: unreachable pattern --> $DIR/empty-types.rs:427:9 | +LL | None => {} + | ---- matches all the values already +LL | // !useful, !reachable LL | _ => {} - | ^ + | ^ unreachable pattern error: unreachable pattern --> $DIR/empty-types.rs:432:9 | +LL | None => {} + | ---- matches all the values already +LL | // !useful, !reachable LL | _a => {} - | ^^ + | ^^ unreachable pattern error[E0004]: non-exhaustive patterns: `&Some(_)` not covered --> $DIR/empty-types.rs:452:11 @@ -569,24 +640,32 @@ error: unreachable pattern | LL | _ => {} | ^ + | + = note: this pattern matches no values because `!` is uninhabited error: unreachable pattern --> $DIR/empty-types.rs:607:9 | LL | _x => {} | ^^ + | + = note: this pattern matches no values because `!` is uninhabited error: unreachable pattern --> $DIR/empty-types.rs:610:9 | LL | _ if false => {} | ^ + | + = note: this pattern matches no values because `!` is uninhabited error: unreachable pattern --> $DIR/empty-types.rs:613:9 | LL | _x if false => {} | ^^ + | + = note: this pattern matches no values because `!` is uninhabited error[E0004]: non-exhaustive patterns: `&_` not covered --> $DIR/empty-types.rs:638:11 diff --git a/tests/ui/pattern/usefulness/empty-types.never_pats.stderr b/tests/ui/pattern/usefulness/empty-types.never_pats.stderr index 0ff2472922e..4856a2f8e08 100644 --- a/tests/ui/pattern/usefulness/empty-types.never_pats.stderr +++ b/tests/ui/pattern/usefulness/empty-types.never_pats.stderr @@ -13,6 +13,7 @@ error: unreachable pattern LL | _ => {} | ^ | + = note: this pattern matches no values because `!` is uninhabited note: the lint level is defined here --> $DIR/empty-types.rs:17:9 | @@ -24,6 +25,8 @@ error: unreachable pattern | LL | _x => {} | ^^ + | + = note: this pattern matches no values because `!` is uninhabited error[E0004]: non-exhaustive patterns: type `&!` is non-empty --> $DIR/empty-types.rs:58:11 @@ -73,6 +76,8 @@ error: unreachable pattern | LL | _ => {} | ^ + | + = note: this pattern matches no values because `!` is uninhabited error[E0004]: non-exhaustive patterns: `Ok(_)` and `Err(!)` not covered --> $DIR/empty-types.rs:91:11 @@ -218,12 +223,16 @@ error: unreachable pattern | LL | _ => {} | ^ + | + = note: this pattern matches no values because `Void` is uninhabited error: unreachable pattern --> $DIR/empty-types.rs:143:13 | LL | _ if false => {} | ^ + | + = note: this pattern matches no values because `Void` is uninhabited error[E0004]: non-exhaustive patterns: `Some(!)` not covered --> $DIR/empty-types.rs:146:15 @@ -266,36 +275,48 @@ error: unreachable pattern | LL | _ => {} | ^ + | + = note: this pattern matches no values because `!` is uninhabited error: unreachable pattern --> $DIR/empty-types.rs:213:13 | LL | _ => {} | ^ + | + = note: this pattern matches no values because `!` is uninhabited error: unreachable pattern --> $DIR/empty-types.rs:218:13 | LL | _ => {} | ^ + | + = note: this pattern matches no values because `!` is uninhabited error: unreachable pattern --> $DIR/empty-types.rs:223:13 | LL | _ => {} | ^ + | + = note: this pattern matches no values because `!` is uninhabited error: unreachable pattern --> $DIR/empty-types.rs:229:13 | LL | _ => {} | ^ + | + = note: this pattern matches no values because `!` is uninhabited error: unreachable pattern --> $DIR/empty-types.rs:288:9 | LL | _ => {} | ^ + | + = note: this pattern matches no values because `!` is uninhabited error[E0004]: non-exhaustive patterns: type `(u32, !)` is non-empty --> $DIR/empty-types.rs:316:11 @@ -460,8 +481,10 @@ LL + } error: unreachable pattern --> $DIR/empty-types.rs:396:9 | +LL | [] => {} + | -- matches all the values already LL | _ => {} - | ^ + | ^ unreachable pattern error[E0004]: non-exhaustive patterns: `[]` not covered --> $DIR/empty-types.rs:398:11 @@ -568,24 +591,32 @@ error: unreachable pattern | LL | _ => {} | ^ + | + = note: this pattern matches no values because `!` is uninhabited error: unreachable pattern --> $DIR/empty-types.rs:607:9 | LL | _x => {} | ^^ + | + = note: this pattern matches no values because `!` is uninhabited error: unreachable pattern --> $DIR/empty-types.rs:610:9 | LL | _ if false => {} | ^ + | + = note: this pattern matches no values because `!` is uninhabited error: unreachable pattern --> $DIR/empty-types.rs:613:9 | LL | _x if false => {} | ^^ + | + = note: this pattern matches no values because `!` is uninhabited error[E0004]: non-exhaustive patterns: `&!` not covered --> $DIR/empty-types.rs:638:11 diff --git a/tests/ui/pattern/usefulness/empty-types.normal.stderr b/tests/ui/pattern/usefulness/empty-types.normal.stderr index 1d13802a2bd..78db9ee349b 100644 --- a/tests/ui/pattern/usefulness/empty-types.normal.stderr +++ b/tests/ui/pattern/usefulness/empty-types.normal.stderr @@ -4,6 +4,7 @@ error: unreachable pattern LL | _ => {} | ^ | + = note: this pattern matches no values because `!` is uninhabited note: the lint level is defined here --> $DIR/empty-types.rs:17:9 | @@ -15,6 +16,8 @@ error: unreachable pattern | LL | _x => {} | ^^ + | + = note: this pattern matches no values because `!` is uninhabited error[E0004]: non-exhaustive patterns: type `&!` is non-empty --> $DIR/empty-types.rs:58:11 @@ -64,6 +67,8 @@ error: unreachable pattern | LL | _ => {} | ^ + | + = note: this pattern matches no values because `!` is uninhabited error[E0004]: non-exhaustive patterns: `Ok(_)` and `Err(_)` not covered --> $DIR/empty-types.rs:91:11 @@ -209,12 +214,16 @@ error: unreachable pattern | LL | _ => {} | ^ + | + = note: this pattern matches no values because `Void` is uninhabited error: unreachable pattern --> $DIR/empty-types.rs:143:13 | LL | _ if false => {} | ^ + | + = note: this pattern matches no values because `Void` is uninhabited error[E0004]: non-exhaustive patterns: `Some(_)` not covered --> $DIR/empty-types.rs:146:15 @@ -257,36 +266,48 @@ error: unreachable pattern | LL | _ => {} | ^ + | + = note: this pattern matches no values because `!` is uninhabited error: unreachable pattern --> $DIR/empty-types.rs:213:13 | LL | _ => {} | ^ + | + = note: this pattern matches no values because `!` is uninhabited error: unreachable pattern --> $DIR/empty-types.rs:218:13 | LL | _ => {} | ^ + | + = note: this pattern matches no values because `!` is uninhabited error: unreachable pattern --> $DIR/empty-types.rs:223:13 | LL | _ => {} | ^ + | + = note: this pattern matches no values because `!` is uninhabited error: unreachable pattern --> $DIR/empty-types.rs:229:13 | LL | _ => {} | ^ + | + = note: this pattern matches no values because `!` is uninhabited error: unreachable pattern --> $DIR/empty-types.rs:288:9 | LL | _ => {} | ^ + | + = note: this pattern matches no values because `!` is uninhabited error[E0004]: non-exhaustive patterns: type `(u32, !)` is non-empty --> $DIR/empty-types.rs:316:11 @@ -451,8 +472,10 @@ LL + } error: unreachable pattern --> $DIR/empty-types.rs:396:9 | +LL | [] => {} + | -- matches all the values already LL | _ => {} - | ^ + | ^ unreachable pattern error[E0004]: non-exhaustive patterns: `[]` not covered --> $DIR/empty-types.rs:398:11 @@ -559,24 +582,32 @@ error: unreachable pattern | LL | _ => {} | ^ + | + = note: this pattern matches no values because `!` is uninhabited error: unreachable pattern --> $DIR/empty-types.rs:607:9 | LL | _x => {} | ^^ + | + = note: this pattern matches no values because `!` is uninhabited error: unreachable pattern --> $DIR/empty-types.rs:610:9 | LL | _ if false => {} | ^ + | + = note: this pattern matches no values because `!` is uninhabited error: unreachable pattern --> $DIR/empty-types.rs:613:9 | LL | _x if false => {} | ^^ + | + = note: this pattern matches no values because `!` is uninhabited error[E0004]: non-exhaustive patterns: `&_` not covered --> $DIR/empty-types.rs:638:11 diff --git a/tests/ui/pattern/usefulness/explain-unreachable-pats.rs b/tests/ui/pattern/usefulness/explain-unreachable-pats.rs new file mode 100644 index 00000000000..98f781b6a09 --- /dev/null +++ b/tests/ui/pattern/usefulness/explain-unreachable-pats.rs @@ -0,0 +1,101 @@ +#![feature(never_type)] +#![feature(min_exhaustive_patterns)] +#![deny(unreachable_patterns)] +//~^ NOTE lint level is defined here + +#[rustfmt::skip] +fn main() { + match (0u8,) { + (1 | 2,) => {} + //~^ NOTE matches all the values already + (2,) => {} + //~^ ERROR unreachable pattern + //~| NOTE unreachable pattern + _ => {} + } + + match (0u8,) { + (1,) => {} + //~^ NOTE matches some of the same values + (2,) => {} + //~^ NOTE matches some of the same values + (1 | 2,) => {} + //~^ ERROR unreachable pattern + //~| NOTE unreachable pattern + //~| NOTE these patterns collectively make the last one unreachable + //~| NOTE collectively making this unreachable + _ => {} + } + + let res: Result<(),!> = Ok(()); + match res { + Ok(_) => {} + Err(_) => {} + //~^ ERROR unreachable pattern + //~| NOTE this pattern matches no values because `!` is uninhabited + } + + #[derive(Copy, Clone)] + enum Void1 {} + #[derive(Copy, Clone)] + enum Void2 {} + // Only an empty type matched _by value_ can make an arm unreachable. We must get the right one. + let res1: Result<(), Void1> = Ok(()); + let res2: Result<(), Void2> = Ok(()); + match (&res1, res2) { + (Err(_), Err(_)) => {} + //~^ ERROR unreachable pattern + //~| NOTE this pattern matches no values because `Void2` is uninhabited + _ => {} + } + match (res1, &res2) { + (Err(_), Err(_)) => {} + //~^ ERROR unreachable pattern + //~| NOTE this pattern matches no values because `Void1` is uninhabited + _ => {} + } + + + if let (0 + //~^ NOTE matches all the values already + | 0, _) = (0, 0) {} + //~^ ERROR unreachable pattern + //~| NOTE unreachable pattern + + match (true, true) { + (_, true) if false => {} // Guarded patterns don't cover others + (true, _) => {} + //~^ NOTE matches some of the same values + (false, _) => {} + //~^ NOTE matches some of the same values + (_, true) => {} + //~^ ERROR unreachable pattern + //~| NOTE unreachable pattern + //~| NOTE these patterns collectively make the last one unreachable + //~| NOTE collectively making this unreachable + } + + match (true, true) { + (true, _) => {} + //~^ NOTE matches all the values already + (false, _) => {} + #[allow(unreachable_patterns)] + (_, true) => {} // Doesn't cover below because it's already unreachable. + (true, true) => {} + //~^ ERROR unreachable pattern + //~| NOTE unreachable pattern + } + + // Despite skipping some irrelevant cases, we still report a set of rows that covers the + // unreachable one. + match (true, true, 0) { + (true, _, _) => {} + (_, true, 0..10) => {} + //~^ NOTE matches all the values already + (_, true, 10..) => {} + (_, true, 3) => {} + //~^ ERROR unreachable pattern + //~| NOTE unreachable pattern + _ => {} + } +} diff --git a/tests/ui/pattern/usefulness/explain-unreachable-pats.stderr b/tests/ui/pattern/usefulness/explain-unreachable-pats.stderr new file mode 100644 index 00000000000..e2eecf4a9f3 --- /dev/null +++ b/tests/ui/pattern/usefulness/explain-unreachable-pats.stderr @@ -0,0 +1,104 @@ +error: unreachable pattern + --> $DIR/explain-unreachable-pats.rs:11:9 + | +LL | (1 | 2,) => {} + | -------- matches all the values already +LL | +LL | (2,) => {} + | ^^^^ unreachable pattern + | +note: the lint level is defined here + --> $DIR/explain-unreachable-pats.rs:3:9 + | +LL | #![deny(unreachable_patterns)] + | ^^^^^^^^^^^^^^^^^^^^ + +error: unreachable pattern + --> $DIR/explain-unreachable-pats.rs:22:9 + | +LL | (1 | 2,) => {} + | ^^^^^^^^ unreachable pattern + | +note: these patterns collectively make the last one unreachable + --> $DIR/explain-unreachable-pats.rs:22:9 + | +LL | (1,) => {} + | ---- matches some of the same values +LL | +LL | (2,) => {} + | ---- matches some of the same values +LL | +LL | (1 | 2,) => {} + | ^^^^^^^^ collectively making this unreachable + +error: unreachable pattern + --> $DIR/explain-unreachable-pats.rs:33:9 + | +LL | Err(_) => {} + | ^^^^^^ + | + = note: this pattern matches no values because `!` is uninhabited + +error: unreachable pattern + --> $DIR/explain-unreachable-pats.rs:46:9 + | +LL | (Err(_), Err(_)) => {} + | ^^^^^^^^^^^^^^^^ + | + = note: this pattern matches no values because `Void2` is uninhabited + +error: unreachable pattern + --> $DIR/explain-unreachable-pats.rs:52:9 + | +LL | (Err(_), Err(_)) => {} + | ^^^^^^^^^^^^^^^^ + | + = note: this pattern matches no values because `Void1` is uninhabited + +error: unreachable pattern + --> $DIR/explain-unreachable-pats.rs:61:11 + | +LL | if let (0 + | - matches all the values already +LL | +LL | | 0, _) = (0, 0) {} + | ^ unreachable pattern + +error: unreachable pattern + --> $DIR/explain-unreachable-pats.rs:71:9 + | +LL | (_, true) => {} + | ^^^^^^^^^ unreachable pattern + | +note: these patterns collectively make the last one unreachable + --> $DIR/explain-unreachable-pats.rs:71:9 + | +LL | (true, _) => {} + | --------- matches some of the same values +LL | +LL | (false, _) => {} + | ---------- matches some of the same values +LL | +LL | (_, true) => {} + | ^^^^^^^^^ collectively making this unreachable + +error: unreachable pattern + --> $DIR/explain-unreachable-pats.rs:84:9 + | +LL | (true, _) => {} + | --------- matches all the values already +... +LL | (true, true) => {} + | ^^^^^^^^^^^^ unreachable pattern + +error: unreachable pattern + --> $DIR/explain-unreachable-pats.rs:96:9 + | +LL | (_, true, 0..10) => {} + | ---------------- matches all the values already +... +LL | (_, true, 3) => {} + | ^^^^^^^^^^^^ unreachable pattern + +error: aborting due to 9 previous errors + diff --git a/tests/ui/pattern/usefulness/floats.stderr b/tests/ui/pattern/usefulness/floats.stderr index 684f6c93a16..d0a8841d6a8 100644 --- a/tests/ui/pattern/usefulness/floats.stderr +++ b/tests/ui/pattern/usefulness/floats.stderr @@ -14,8 +14,10 @@ LL + _ => todo!() error: unreachable pattern --> $DIR/floats.rs:18:9 | +LL | 0.01f16..=6.5f16 => {} + | ---------------- matches all the values already LL | 0.01f16 => {} - | ^^^^^^^ + | ^^^^^^^ unreachable pattern | note: the lint level is defined here --> $DIR/floats.rs:1:9 @@ -26,80 +28,118 @@ LL | #![deny(unreachable_patterns)] error: unreachable pattern --> $DIR/floats.rs:19:9 | +LL | 0.01f16..=6.5f16 => {} + | ---------------- matches all the values already +LL | 0.01f16 => {} LL | 0.02f16 => {} - | ^^^^^^^ + | ^^^^^^^ unreachable pattern error: unreachable pattern --> $DIR/floats.rs:20:9 | +LL | 0.01f16..=6.5f16 => {} + | ---------------- matches all the values already +... LL | 6.5f16 => {} - | ^^^^^^ + | ^^^^^^ unreachable pattern error: unreachable pattern --> $DIR/floats.rs:31:9 | +LL | 0.01f32..=6.5f32 => {} + | ---------------- matches all the values already LL | 0.01f32 => {} - | ^^^^^^^ + | ^^^^^^^ unreachable pattern error: unreachable pattern --> $DIR/floats.rs:32:9 | +LL | 0.01f32..=6.5f32 => {} + | ---------------- matches all the values already +LL | 0.01f32 => {} LL | 0.02f32 => {} - | ^^^^^^^ + | ^^^^^^^ unreachable pattern error: unreachable pattern --> $DIR/floats.rs:33:9 | +LL | 0.01f32..=6.5f32 => {} + | ---------------- matches all the values already +... LL | 6.5f32 => {} - | ^^^^^^ + | ^^^^^^ unreachable pattern error: unreachable pattern --> $DIR/floats.rs:45:9 | +LL | 0.01f64..=6.5f64 => {} + | ---------------- matches all the values already +LL | 0.005f64 => {} LL | 0.01f64 => {} - | ^^^^^^^ + | ^^^^^^^ unreachable pattern error: unreachable pattern --> $DIR/floats.rs:46:9 | +LL | 0.01f64..=6.5f64 => {} + | ---------------- matches all the values already +... LL | 0.02f64 => {} - | ^^^^^^^ + | ^^^^^^^ unreachable pattern error: unreachable pattern --> $DIR/floats.rs:47:9 | +LL | 0.01f64..=6.5f64 => {} + | ---------------- matches all the values already +... LL | 6.5f64 => {} - | ^^^^^^ + | ^^^^^^ unreachable pattern error: unreachable pattern --> $DIR/floats.rs:49:9 | +LL | 0.01f64..=6.5f64 => {} + | ---------------- matches all the values already +... LL | 1.0f64..=4.0f64 => {} - | ^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^ unreachable pattern error: unreachable pattern --> $DIR/floats.rs:62:9 | +LL | 0.01f128..=6.5f128 => {} + | ------------------ matches all the values already +LL | 0.005f128 => {} LL | 0.01f128 => {} - | ^^^^^^^^ + | ^^^^^^^^ unreachable pattern error: unreachable pattern --> $DIR/floats.rs:63:9 | +LL | 0.01f128..=6.5f128 => {} + | ------------------ matches all the values already +... LL | 0.02f128 => {} - | ^^^^^^^^ + | ^^^^^^^^ unreachable pattern error: unreachable pattern --> $DIR/floats.rs:64:9 | +LL | 0.01f128..=6.5f128 => {} + | ------------------ matches all the values already +... LL | 6.5f128 => {} - | ^^^^^^^ + | ^^^^^^^ unreachable pattern error: unreachable pattern --> $DIR/floats.rs:66:9 | +LL | 0.01f128..=6.5f128 => {} + | ------------------ matches all the values already +... LL | 1.0f128..=4.0f128 => {} - | ^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^ unreachable pattern error: aborting due to 15 previous errors diff --git a/tests/ui/pattern/usefulness/impl-trait.stderr b/tests/ui/pattern/usefulness/impl-trait.stderr index ba8b12f9f66..c079f5a259d 100644 --- a/tests/ui/pattern/usefulness/impl-trait.stderr +++ b/tests/ui/pattern/usefulness/impl-trait.stderr @@ -4,6 +4,7 @@ error: unreachable pattern LL | _ => {} | ^ | + = note: this pattern matches no values because `Void` is uninhabited note: the lint level is defined here --> $DIR/impl-trait.rs:5:9 | @@ -15,36 +16,48 @@ error: unreachable pattern | LL | _ => {} | ^ + | + = note: this pattern matches no values because `Void` is uninhabited error: unreachable pattern --> $DIR/impl-trait.rs:45:13 | LL | Some(_) => {} | ^^^^^^^ + | + = note: this pattern matches no values because `Void` is uninhabited error: unreachable pattern --> $DIR/impl-trait.rs:49:13 | +LL | None => {} + | ---- matches all the values already LL | _ => {} - | ^ + | ^ unreachable pattern error: unreachable pattern --> $DIR/impl-trait.rs:59:13 | LL | Some(_) => {} | ^^^^^^^ + | + = note: this pattern matches no values because `Void` is uninhabited error: unreachable pattern --> $DIR/impl-trait.rs:63:13 | +LL | None => {} + | ---- matches all the values already LL | _ => {} - | ^ + | ^ unreachable pattern error: unreachable pattern --> $DIR/impl-trait.rs:76:9 | LL | _ => {} | ^ + | + = note: this pattern matches no values because `Void` is uninhabited error: unreachable pattern --> $DIR/impl-trait.rs:86:9 @@ -59,12 +72,16 @@ error: unreachable pattern | LL | _ => {} | ^ + | + = note: this pattern matches no values because `Void` is uninhabited error: unreachable pattern --> $DIR/impl-trait.rs:105:9 | +LL | Some((a, b)) => {} + | ------------ matches all the values already LL | Some((mut x, mut y)) => { - | ^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^ unreachable pattern error: unreachable pattern --> $DIR/impl-trait.rs:124:13 @@ -79,12 +96,16 @@ error: unreachable pattern | LL | _ => {} | ^ + | + = note: this pattern matches no values because `SecretelyVoid` is uninhabited error: unreachable pattern --> $DIR/impl-trait.rs:151:13 | LL | _ => {} | ^ + | + = note: this pattern matches no values because `SecretelyDoubleVoid` is uninhabited error[E0004]: non-exhaustive patterns: type `impl Copy` is non-empty --> $DIR/impl-trait.rs:23:11 diff --git a/tests/ui/pattern/usefulness/integer-ranges/reachability.stderr b/tests/ui/pattern/usefulness/integer-ranges/reachability.stderr index c5b028d2038..5d86007a853 100644 --- a/tests/ui/pattern/usefulness/integer-ranges/reachability.stderr +++ b/tests/ui/pattern/usefulness/integer-ranges/reachability.stderr @@ -2,7 +2,9 @@ error: unreachable pattern --> $DIR/reachability.rs:18:17 | LL | m!(0u8, 42, 42); - | ^^ + | -- ^^ unreachable pattern + | | + | matches all the values already | note: the lint level is defined here --> $DIR/reachability.rs:3:9 @@ -14,121 +16,211 @@ error: unreachable pattern --> $DIR/reachability.rs:22:22 | LL | m!(0u8, 20..=30, 20); - | ^^ + | ------- ^^ unreachable pattern + | | + | matches all the values already error: unreachable pattern --> $DIR/reachability.rs:23:22 | LL | m!(0u8, 20..=30, 21); - | ^^ + | ------- ^^ unreachable pattern + | | + | matches all the values already error: unreachable pattern --> $DIR/reachability.rs:24:22 | LL | m!(0u8, 20..=30, 25); - | ^^ + | ------- ^^ unreachable pattern + | | + | matches all the values already error: unreachable pattern --> $DIR/reachability.rs:25:22 | LL | m!(0u8, 20..=30, 29); - | ^^ + | ------- ^^ unreachable pattern + | | + | matches all the values already error: unreachable pattern --> $DIR/reachability.rs:26:22 | LL | m!(0u8, 20..=30, 30); - | ^^ + | ------- ^^ unreachable pattern + | | + | matches all the values already error: unreachable pattern --> $DIR/reachability.rs:29:21 | LL | m!(0u8, 20..30, 20); - | ^^ + | ------ ^^ unreachable pattern + | | + | matches all the values already error: unreachable pattern --> $DIR/reachability.rs:30:21 | LL | m!(0u8, 20..30, 21); - | ^^ + | ------ ^^ unreachable pattern + | | + | matches all the values already error: unreachable pattern --> $DIR/reachability.rs:31:21 | LL | m!(0u8, 20..30, 25); - | ^^ + | ------ ^^ unreachable pattern + | | + | matches all the values already error: unreachable pattern --> $DIR/reachability.rs:32:21 | LL | m!(0u8, 20..30, 29); - | ^^ + | ------ ^^ unreachable pattern + | | + | matches all the values already error: unreachable pattern --> $DIR/reachability.rs:36:22 | LL | m!(0u8, 20..=30, 20..=30); - | ^^^^^^^ + | ------- ^^^^^^^ unreachable pattern + | | + | matches all the values already error: unreachable pattern --> $DIR/reachability.rs:37:22 | LL | m!(0u8, 20.. 30, 20.. 30); - | ^^^^^^^ + | ------- ^^^^^^^ unreachable pattern + | | + | matches all the values already error: unreachable pattern --> $DIR/reachability.rs:38:22 | LL | m!(0u8, 20..=30, 20.. 30); - | ^^^^^^^ + | ------- ^^^^^^^ unreachable pattern + | | + | matches all the values already error: unreachable pattern --> $DIR/reachability.rs:40:22 | LL | m!(0u8, 20..=30, 21..=30); - | ^^^^^^^ + | ------- ^^^^^^^ unreachable pattern + | | + | matches all the values already error: unreachable pattern --> $DIR/reachability.rs:41:22 | LL | m!(0u8, 20..=30, 20..=29); - | ^^^^^^^ + | ------- ^^^^^^^ unreachable pattern + | | + | matches all the values already error: unreachable pattern --> $DIR/reachability.rs:43:24 | LL | m!('a', 'A'..='z', 'a'..='z'); - | ^^^^^^^^^ + | --------- ^^^^^^^^^ unreachable pattern + | | + | matches all the values already error: unreachable pattern --> $DIR/reachability.rs:50:9 | LL | 5..=8 => {}, - | ^^^^^ + | ^^^^^ unreachable pattern + | +note: these patterns collectively make the last one unreachable + --> $DIR/reachability.rs:50:9 + | +LL | 5 => {}, + | - matches some of the same values +LL | 6 => {}, + | - matches some of the same values +LL | 7 => {}, + | - matches some of the same values +LL | 8 => {}, + | - matches some of the same values +LL | 5..=8 => {}, + | ^^^^^ collectively making this unreachable error: unreachable pattern --> $DIR/reachability.rs:56:9 | LL | 5..15 => {}, - | ^^^^^ + | ^^^^^ unreachable pattern + | +note: these patterns collectively make the last one unreachable + --> $DIR/reachability.rs:56:9 + | +LL | 0..10 => {}, + | ----- matches some of the same values +LL | 10..20 => {}, + | ------ matches some of the same values +LL | 5..15 => {}, + | ^^^^^ collectively making this unreachable error: unreachable pattern --> $DIR/reachability.rs:63:9 | LL | 5..25 => {}, - | ^^^^^ + | ^^^^^ unreachable pattern + | +note: these patterns collectively make the last one unreachable + --> $DIR/reachability.rs:63:9 + | +LL | 0..10 => {}, + | ----- matches some of the same values +LL | 10..20 => {}, + | ------ matches some of the same values +LL | 20..30 => {}, + | ------ matches some of the same values +LL | 5..25 => {}, + | ^^^^^ collectively making this unreachable error: unreachable pattern --> $DIR/reachability.rs:71:9 | LL | 5..25 => {}, - | ^^^^^ + | ^^^^^ unreachable pattern + | +note: these patterns collectively make the last one unreachable + --> $DIR/reachability.rs:71:9 + | +LL | 0..10 => {}, + | ----- matches some of the same values +LL | 10 => {}, + | -- matches some of the same values +LL | 11..=23 => {}, + | ------- matches some of the same values +LL | 19..30 => {}, + | ------ matches some of the same values +LL | 5..25 => {}, + | ^^^^^ collectively making this unreachable error: unreachable pattern --> $DIR/reachability.rs:77:9 | LL | 5..15 => {}, - | ^^^^^ + | ^^^^^ unreachable pattern + | +note: these patterns collectively make the last one unreachable + --> $DIR/reachability.rs:77:9 + | +LL | 0..10 => {}, + | ----- matches some of the same values +LL | 10..20 => {}, + | ------ matches some of the same values +LL | 5..15 => {}, + | ^^^^^ collectively making this unreachable error: unreachable pattern --> $DIR/reachability.rs:84:9 @@ -142,19 +234,34 @@ error: unreachable pattern --> $DIR/reachability.rs:89:9 | LL | '\u{D7FF}'..='\u{E000}' => {}, - | ^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^ unreachable pattern + | +note: these patterns collectively make the last one unreachable + --> $DIR/reachability.rs:89:9 + | +LL | '\u{0}'..='\u{D7FF}' => {}, + | -------------------- matches some of the same values +LL | '\u{E000}'..='\u{10_FFFF}' => {}, + | -------------------------- matches some of the same values +LL | '\u{D7FF}'..='\u{E000}' => {}, + | ^^^^^^^^^^^^^^^^^^^^^^^ collectively making this unreachable error: unreachable pattern --> $DIR/reachability.rs:105:9 | +LL | &42 => {} + | --- matches all the values already LL | &FOO => {} - | ^^^^ + | ^^^^ unreachable pattern error: unreachable pattern --> $DIR/reachability.rs:106:9 | +LL | &42 => {} + | --- matches all the values already +LL | &FOO => {} LL | BAR => {} - | ^^^ + | ^^^ unreachable pattern error: aborting due to 25 previous errors diff --git a/tests/ui/pattern/usefulness/issue-12116.stderr b/tests/ui/pattern/usefulness/issue-12116.stderr index 199bdc6ac97..b2c2be97563 100644 --- a/tests/ui/pattern/usefulness/issue-12116.stderr +++ b/tests/ui/pattern/usefulness/issue-12116.stderr @@ -1,8 +1,10 @@ error: unreachable pattern --> $DIR/issue-12116.rs:15:9 | +LL | &IntList::Cons(val, box ref next_list) => tail(next_list), + | -------------------------------------- matches all the values already LL | &IntList::Cons(val, box IntList::Nil) => IntList::Cons(val, Box::new(IntList::Nil)), - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unreachable pattern | note: the lint level is defined here --> $DIR/issue-12116.rs:4:9 diff --git a/tests/ui/pattern/usefulness/issue-12369.stderr b/tests/ui/pattern/usefulness/issue-12369.stderr index 2b6e2e14b7c..7754cbc2484 100644 --- a/tests/ui/pattern/usefulness/issue-12369.stderr +++ b/tests/ui/pattern/usefulness/issue-12369.stderr @@ -2,8 +2,17 @@ error: unreachable pattern --> $DIR/issue-12369.rs:9:9 | LL | &[10,a, ref rest @ ..] => 10 - | ^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^ unreachable pattern | +note: these patterns collectively make the last one unreachable + --> $DIR/issue-12369.rs:9:9 + | +LL | &[a,b,c] => 3, + | -------- matches some of the same values +LL | &[a, ref rest @ ..] => a, + | ------------------- matches some of the same values +LL | &[10,a, ref rest @ ..] => 10 + | ^^^^^^^^^^^^^^^^^^^^^^ collectively making this unreachable note: the lint level is defined here --> $DIR/issue-12369.rs:1:9 | diff --git a/tests/ui/pattern/usefulness/issue-13727.stderr b/tests/ui/pattern/usefulness/issue-13727.stderr index ab80c56ea88..ca8533b33a4 100644 --- a/tests/ui/pattern/usefulness/issue-13727.stderr +++ b/tests/ui/pattern/usefulness/issue-13727.stderr @@ -1,8 +1,10 @@ error: unreachable pattern --> $DIR/issue-13727.rs:7:5 | +LL | 256 => print!("0b1110\n"), + | --- matches all the values already LL | 512 => print!("0b1111\n"), - | ^^^ + | ^^^ unreachable pattern | note: the lint level is defined here --> $DIR/issue-13727.rs:2:9 diff --git a/tests/ui/pattern/usefulness/issue-30240-b.stderr b/tests/ui/pattern/usefulness/issue-30240-b.stderr index 74d39eba98c..749515fc94b 100644 --- a/tests/ui/pattern/usefulness/issue-30240-b.stderr +++ b/tests/ui/pattern/usefulness/issue-30240-b.stderr @@ -2,7 +2,9 @@ error: unreachable pattern --> $DIR/issue-30240-b.rs:12:9 | LL | "hello" => {} - | ^^^^^^^ + | ------- matches all the values already +LL | "hello" => {} + | ^^^^^^^ unreachable pattern | note: the lint level is defined here --> $DIR/issue-30240-b.rs:1:9 diff --git a/tests/ui/pattern/usefulness/issue-31221.stderr b/tests/ui/pattern/usefulness/issue-31221.stderr index 7d349144456..596f4d8096d 100644 --- a/tests/ui/pattern/usefulness/issue-31221.stderr +++ b/tests/ui/pattern/usefulness/issue-31221.stderr @@ -23,10 +23,18 @@ LL | &Var2 => (), error: unreachable pattern --> $DIR/issue-31221.rs:31:9 | -LL | (c, d) => (), - | ------ matches any value LL | anything => () | ^^^^^^^^ unreachable pattern + | +note: these patterns collectively make the last one unreachable + --> $DIR/issue-31221.rs:31:9 + | +LL | (Var1, b) => (), + | --------- matches some of the same values +LL | (c, d) => (), + | ------ matches some of the same values +LL | anything => () + | ^^^^^^^^ collectively making this unreachable error: aborting due to 3 previous errors diff --git a/tests/ui/pattern/usefulness/issue-57472.stderr b/tests/ui/pattern/usefulness/issue-57472.stderr index c814eaec0d1..68b5b7cb791 100644 --- a/tests/ui/pattern/usefulness/issue-57472.stderr +++ b/tests/ui/pattern/usefulness/issue-57472.stderr @@ -1,8 +1,10 @@ error: unreachable pattern --> $DIR/issue-57472.rs:15:13 | +LL | Punned { foo: [_], .. } => println!("foo"), + | ----------------------- matches all the values already LL | Punned { bar: [_], .. } => println!("bar"), - | ^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^ unreachable pattern | note: the lint level is defined here --> $DIR/issue-57472.rs:2:9 @@ -13,8 +15,10 @@ LL | #![deny(unreachable_patterns)] error: unreachable pattern --> $DIR/issue-57472.rs:32:17 | +LL | Punned { foo: [_] } => println!("foo"), + | ------------------- matches all the values already LL | Punned { bar: [_] } => println!("bar"), - | ^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^ unreachable pattern error: aborting due to 2 previous errors diff --git a/tests/ui/pattern/usefulness/match-arm-statics.stderr b/tests/ui/pattern/usefulness/match-arm-statics.stderr index a5dffebf699..b6f2b47047d 100644 --- a/tests/ui/pattern/usefulness/match-arm-statics.stderr +++ b/tests/ui/pattern/usefulness/match-arm-statics.stderr @@ -1,8 +1,11 @@ error: unreachable pattern --> $DIR/match-arm-statics.rs:25:9 | +LL | TRUE_TRUE => (), + | --------- matches all the values already +... LL | (true, true) => () - | ^^^^^^^^^^^^ + | ^^^^^^^^^^^^ unreachable pattern | note: the lint level is defined here --> $DIR/match-arm-statics.rs:2:9 @@ -13,14 +16,29 @@ LL | #![deny(unreachable_patterns)] error: unreachable pattern --> $DIR/match-arm-statics.rs:40:9 | +LL | Some(Some(EAST)) => (), + | ---------------- matches all the values already +... LL | Some(Some(East)) => (), - | ^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^ unreachable pattern error: unreachable pattern --> $DIR/match-arm-statics.rs:60:9 | LL | Foo { bar: Some(EAST), baz: NewBool(false) } => () - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unreachable pattern + | +note: these patterns collectively make the last one unreachable + --> $DIR/match-arm-statics.rs:60:9 + | +LL | Foo { bar: _, baz: NEW_FALSE } => (), + | ------------------------------ matches some of the same values +... +LL | Foo { bar: Some(EAST), .. } => (), + | --------------------------- matches some of the same values +LL | Foo { bar: Some(North), baz: NewBool(true) } => (), +LL | Foo { bar: Some(EAST), baz: NewBool(false) } => () + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ collectively making this unreachable error: aborting due to 3 previous errors diff --git a/tests/ui/pattern/usefulness/match-byte-array-patterns.stderr b/tests/ui/pattern/usefulness/match-byte-array-patterns.stderr index 0c582be8df8..39675e2bdd4 100644 --- a/tests/ui/pattern/usefulness/match-byte-array-patterns.stderr +++ b/tests/ui/pattern/usefulness/match-byte-array-patterns.stderr @@ -1,8 +1,10 @@ error: unreachable pattern --> $DIR/match-byte-array-patterns.rs:8:9 | +LL | b"AAAA" => {}, + | ------- matches all the values already LL | &[0x41, 0x41, 0x41, 0x41] => {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^ unreachable pattern | note: the lint level is defined here --> $DIR/match-byte-array-patterns.rs:1:9 @@ -13,44 +15,58 @@ LL | #![deny(unreachable_patterns)] error: unreachable pattern --> $DIR/match-byte-array-patterns.rs:14:9 | +LL | &[0x41, 0x41, 0x41, 0x41] => {} + | ------------------------- matches all the values already LL | b"AAAA" => {}, - | ^^^^^^^ + | ^^^^^^^ unreachable pattern error: unreachable pattern --> $DIR/match-byte-array-patterns.rs:20:9 | +LL | &[_, 0x41, 0x41, 0x41] => {}, + | ---------------------- matches all the values already LL | b"AAAA" => {}, - | ^^^^^^^ + | ^^^^^^^ unreachable pattern error: unreachable pattern --> $DIR/match-byte-array-patterns.rs:26:9 | +LL | &[0x41, .., 0x41] => {} + | ----------------- matches all the values already LL | b"AAAA" => {}, - | ^^^^^^^ + | ^^^^^^^ unreachable pattern error: unreachable pattern --> $DIR/match-byte-array-patterns.rs:34:9 | +LL | b"AAAA" => {}, + | ------- matches all the values already LL | &[0x41, 0x41, 0x41, 0x41] => {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^ unreachable pattern error: unreachable pattern --> $DIR/match-byte-array-patterns.rs:40:9 | +LL | &[0x41, 0x41, 0x41, 0x41] => {} + | ------------------------- matches all the values already LL | b"AAAA" => {}, - | ^^^^^^^ + | ^^^^^^^ unreachable pattern error: unreachable pattern --> $DIR/match-byte-array-patterns.rs:46:9 | +LL | &[_, 0x41, 0x41, 0x41] => {}, + | ---------------------- matches all the values already LL | b"AAAA" => {}, - | ^^^^^^^ + | ^^^^^^^ unreachable pattern error: unreachable pattern --> $DIR/match-byte-array-patterns.rs:52:9 | +LL | &[0x41, .., 0x41] => {} + | ----------------- matches all the values already LL | b"AAAA" => {}, - | ^^^^^^^ + | ^^^^^^^ unreachable pattern error: aborting due to 8 previous errors diff --git a/tests/ui/pattern/usefulness/match-ref-ice.stderr b/tests/ui/pattern/usefulness/match-ref-ice.stderr index 0dbfa776f69..9c5af47cc1e 100644 --- a/tests/ui/pattern/usefulness/match-ref-ice.stderr +++ b/tests/ui/pattern/usefulness/match-ref-ice.stderr @@ -1,8 +1,10 @@ error: unreachable pattern --> $DIR/match-ref-ice.rs:13:9 | +LL | [1, ref _madoka, 3] => (), + | ------------------- matches all the values already LL | [1, 2, 3] => (), - | ^^^^^^^^^ + | ^^^^^^^^^ unreachable pattern | note: the lint level is defined here --> $DIR/match-ref-ice.rs:1:9 diff --git a/tests/ui/pattern/usefulness/match-vec-fixed.stderr b/tests/ui/pattern/usefulness/match-vec-fixed.stderr index e388a06cb9a..04507a22856 100644 --- a/tests/ui/pattern/usefulness/match-vec-fixed.stderr +++ b/tests/ui/pattern/usefulness/match-vec-fixed.stderr @@ -2,7 +2,9 @@ error: unreachable pattern --> $DIR/match-vec-fixed.rs:7:9 | LL | [_, _, _] => {} - | ^^^^^^^^^ + | --------- matches all the values already +LL | [_, _, _] => {} + | ^^^^^^^^^ unreachable pattern | note: the lint level is defined here --> $DIR/match-vec-fixed.rs:1:9 @@ -14,7 +16,9 @@ error: unreachable pattern --> $DIR/match-vec-fixed.rs:11:9 | LL | [_, 1, _] => {} - | ^^^^^^^^^ + | --------- matches all the values already +LL | [_, 1, _] => {} + | ^^^^^^^^^ unreachable pattern error: aborting due to 2 previous errors diff --git a/tests/ui/pattern/usefulness/match-vec-unreachable.stderr b/tests/ui/pattern/usefulness/match-vec-unreachable.stderr index 672fd92fb5e..865f5b319a7 100644 --- a/tests/ui/pattern/usefulness/match-vec-unreachable.stderr +++ b/tests/ui/pattern/usefulness/match-vec-unreachable.stderr @@ -1,8 +1,10 @@ error: unreachable pattern --> $DIR/match-vec-unreachable.rs:8:9 | +LL | [a, (2, 3), _] => (), + | -------------- matches all the values already LL | [(1, 2), (2, 3), b] => (), - | ^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^ unreachable pattern | note: the lint level is defined here --> $DIR/match-vec-unreachable.rs:1:9 @@ -13,14 +15,18 @@ LL | #![deny(unreachable_patterns)] error: unreachable pattern --> $DIR/match-vec-unreachable.rs:18:9 | +LL | [ref a, _, _, ..] => { println!("{}", a); } + | ----------------- matches all the values already LL | [_, _, _, _, _] => { } - | ^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^ unreachable pattern error: unreachable pattern --> $DIR/match-vec-unreachable.rs:26:9 | +LL | ['a', 'b', 'c', ref _tail @ ..] => {} + | ------------------------------- matches all the values already LL | ['a', 'b', 'c'] => {} - | ^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^ unreachable pattern error: aborting due to 3 previous errors diff --git a/tests/ui/pattern/usefulness/slice-pattern-const-2.stderr b/tests/ui/pattern/usefulness/slice-pattern-const-2.stderr index dcad11a38a7..12db48590a4 100644 --- a/tests/ui/pattern/usefulness/slice-pattern-const-2.stderr +++ b/tests/ui/pattern/usefulness/slice-pattern-const-2.stderr @@ -1,8 +1,11 @@ error: unreachable pattern --> $DIR/slice-pattern-const-2.rs:9:9 | +LL | MAGIC_TEST => (), + | ---------- matches all the values already +LL | [0x00, 0x00, 0x00, 0x00] => (), LL | [4, 5, 6, 7] => (), - | ^^^^^^^^^^^^ + | ^^^^^^^^^^^^ unreachable pattern | note: the lint level is defined here --> $DIR/slice-pattern-const-2.rs:1:9 @@ -13,20 +16,26 @@ LL | #![deny(unreachable_patterns)] error: unreachable pattern --> $DIR/slice-pattern-const-2.rs:15:9 | +LL | MAGIC_TEST => (), + | ---------- matches all the values already LL | [4, 5, 6, 7] => (), - | ^^^^^^^^^^^^ + | ^^^^^^^^^^^^ unreachable pattern error: unreachable pattern --> $DIR/slice-pattern-const-2.rs:21:9 | +LL | [4, 5, 6, 7] => (), + | ------------ matches all the values already LL | MAGIC_TEST => (), - | ^^^^^^^^^^ + | ^^^^^^^^^^ unreachable pattern error: unreachable pattern --> $DIR/slice-pattern-const-2.rs:28:9 | +LL | [4] => (), + | --- matches all the values already LL | FOO => (), - | ^^^ + | ^^^ unreachable pattern error: aborting due to 4 previous errors diff --git a/tests/ui/pattern/usefulness/slice-pattern-const-3.stderr b/tests/ui/pattern/usefulness/slice-pattern-const-3.stderr index b90b3a88a18..5a66799d9c9 100644 --- a/tests/ui/pattern/usefulness/slice-pattern-const-3.stderr +++ b/tests/ui/pattern/usefulness/slice-pattern-const-3.stderr @@ -1,8 +1,11 @@ error: unreachable pattern --> $DIR/slice-pattern-const-3.rs:9:9 | +LL | MAGIC_TEST => (), + | ---------- matches all the values already +LL | ["0x00", "0x00", "0x00", "0x00"] => (), LL | ["4", "5", "6", "7"] => (), - | ^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^ unreachable pattern | note: the lint level is defined here --> $DIR/slice-pattern-const-3.rs:1:9 @@ -13,20 +16,26 @@ LL | #![deny(unreachable_patterns)] error: unreachable pattern --> $DIR/slice-pattern-const-3.rs:15:9 | +LL | MAGIC_TEST => (), + | ---------- matches all the values already LL | ["4", "5", "6", "7"] => (), - | ^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^ unreachable pattern error: unreachable pattern --> $DIR/slice-pattern-const-3.rs:21:9 | +LL | ["4", "5", "6", "7"] => (), + | -------------------- matches all the values already LL | MAGIC_TEST => (), - | ^^^^^^^^^^ + | ^^^^^^^^^^ unreachable pattern error: unreachable pattern --> $DIR/slice-pattern-const-3.rs:28:9 | +LL | ["boo"] => (), + | ------- matches all the values already LL | FOO => (), - | ^^^ + | ^^^ unreachable pattern error: aborting due to 4 previous errors diff --git a/tests/ui/pattern/usefulness/slice-pattern-const.stderr b/tests/ui/pattern/usefulness/slice-pattern-const.stderr index 1fffb9fedbf..87a85acc4c5 100644 --- a/tests/ui/pattern/usefulness/slice-pattern-const.stderr +++ b/tests/ui/pattern/usefulness/slice-pattern-const.stderr @@ -1,8 +1,11 @@ error: unreachable pattern --> $DIR/slice-pattern-const.rs:9:9 | +LL | MAGIC_TEST => (), + | ---------- matches all the values already +LL | [0x00, 0x00, 0x00, 0x00] => (), LL | [84, 69, 83, 84] => (), - | ^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^ unreachable pattern | note: the lint level is defined here --> $DIR/slice-pattern-const.rs:1:9 @@ -13,50 +16,68 @@ LL | #![deny(unreachable_patterns)] error: unreachable pattern --> $DIR/slice-pattern-const.rs:15:9 | +LL | MAGIC_TEST => (), + | ---------- matches all the values already LL | [84, 69, 83, 84] => (), - | ^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^ unreachable pattern error: unreachable pattern --> $DIR/slice-pattern-const.rs:21:9 | +LL | [84, 69, 83, 84] => (), + | ---------------- matches all the values already LL | MAGIC_TEST => (), - | ^^^^^^^^^^ + | ^^^^^^^^^^ unreachable pattern error: unreachable pattern --> $DIR/slice-pattern-const.rs:28:9 | +LL | [4] => (), + | --- matches all the values already LL | FOO => (), - | ^^^ + | ^^^ unreachable pattern error: unreachable pattern --> $DIR/slice-pattern-const.rs:35:9 | +LL | [4] => (), + | --- matches all the values already LL | BAR => (), - | ^^^ + | ^^^ unreachable pattern error: unreachable pattern --> $DIR/slice-pattern-const.rs:43:9 | +LL | [] => (), + | -- matches all the values already LL | BOO => (), - | ^^^ + | ^^^ unreachable pattern error: unreachable pattern --> $DIR/slice-pattern-const.rs:44:9 | +LL | [] => (), + | -- matches all the values already +LL | BOO => (), LL | b"" => (), - | ^^^ + | ^^^ unreachable pattern error: unreachable pattern --> $DIR/slice-pattern-const.rs:45:9 | +LL | [] => (), + | -- matches all the values already +... LL | _ => (), - | ^ + | ^ unreachable pattern error: unreachable pattern --> $DIR/slice-pattern-const.rs:51:9 | +LL | CONST1 => {} + | ------ matches all the values already LL | [true] => {} - | ^^^^^^ + | ^^^^^^ unreachable pattern error: aborting due to 9 previous errors diff --git a/tests/ui/pattern/usefulness/slice-patterns-reachability.stderr b/tests/ui/pattern/usefulness/slice-patterns-reachability.stderr index 607ffb76595..40fbb00de1f 100644 --- a/tests/ui/pattern/usefulness/slice-patterns-reachability.stderr +++ b/tests/ui/pattern/usefulness/slice-patterns-reachability.stderr @@ -2,7 +2,9 @@ error: unreachable pattern --> $DIR/slice-patterns-reachability.rs:8:9 | LL | [true, ..] => {} - | ^^^^^^^^^^ + | ---------- matches all the values already +LL | [true, ..] => {} + | ^^^^^^^^^^ unreachable pattern | note: the lint level is defined here --> $DIR/slice-patterns-reachability.rs:1:9 @@ -13,32 +15,45 @@ LL | #![deny(unreachable_patterns)] error: unreachable pattern --> $DIR/slice-patterns-reachability.rs:9:9 | +LL | [true, ..] => {} + | ---------- matches all the values already +LL | [true, ..] => {} LL | [true] => {} - | ^^^^^^ + | ^^^^^^ unreachable pattern error: unreachable pattern --> $DIR/slice-patterns-reachability.rs:14:9 | LL | [.., true] => {} - | ^^^^^^^^^^ + | ---------- matches all the values already +LL | [.., true] => {} + | ^^^^^^^^^^ unreachable pattern error: unreachable pattern --> $DIR/slice-patterns-reachability.rs:15:9 | +LL | [.., true] => {} + | ---------- matches all the values already +LL | [.., true] => {} LL | [true] => {} - | ^^^^^^ + | ^^^^^^ unreachable pattern error: unreachable pattern --> $DIR/slice-patterns-reachability.rs:20:9 | LL | [false, .., true] => {} - | ^^^^^^^^^^^^^^^^^ + | ----------------- matches all the values already +LL | [false, .., true] => {} + | ^^^^^^^^^^^^^^^^^ unreachable pattern error: unreachable pattern --> $DIR/slice-patterns-reachability.rs:21:9 | +LL | [false, .., true] => {} + | ----------------- matches all the values already +LL | [false, .., true] => {} LL | [false, true] => {} - | ^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^ unreachable pattern error: aborting due to 6 previous errors diff --git a/tests/ui/pattern/usefulness/top-level-alternation.stderr b/tests/ui/pattern/usefulness/top-level-alternation.stderr index 17fa951c539..ad846f23155 100644 --- a/tests/ui/pattern/usefulness/top-level-alternation.stderr +++ b/tests/ui/pattern/usefulness/top-level-alternation.stderr @@ -2,7 +2,9 @@ error: unreachable pattern --> $DIR/top-level-alternation.rs:4:23 | LL | while let 0..=2 | 1 = 0 {} - | ^ + | ----- ^ unreachable pattern + | | + | matches all the values already | note: the lint level is defined here --> $DIR/top-level-alternation.rs:1:9 @@ -14,61 +16,90 @@ error: unreachable pattern --> $DIR/top-level-alternation.rs:5:20 | LL | if let 0..=2 | 1 = 0 {} - | ^ + | ----- ^ unreachable pattern + | | + | matches all the values already error: unreachable pattern --> $DIR/top-level-alternation.rs:9:15 | +LL | 0 + | - matches all the values already LL | | 0 => {} - | ^ + | ^ unreachable pattern error: unreachable pattern --> $DIR/top-level-alternation.rs:14:15 | +LL | Some(0) + | ------- matches all the values already LL | | Some(0) => {} - | ^^^^^^^ + | ^^^^^^^ unreachable pattern error: unreachable pattern --> $DIR/top-level-alternation.rs:19:9 | +LL | (0, _) | (_, 0) => {} + | --------------- matches all the values already LL | (0, 0) => {} - | ^^^^^^ + | ^^^^^^ unreachable pattern error: unreachable pattern --> $DIR/top-level-alternation.rs:39:9 | +LL | None | Some(_) => {} + | -------------- matches all the values already LL | _ => {} - | ^ + | ^ unreachable pattern error: unreachable pattern --> $DIR/top-level-alternation.rs:43:9 | +LL | None | Some(_) => {} + | -------------- matches all the values already LL | Some(_) => {} - | ^^^^^^^ + | ^^^^^^^ unreachable pattern error: unreachable pattern --> $DIR/top-level-alternation.rs:44:9 | +LL | None | Some(_) => {} + | -------------- matches all the values already +LL | Some(_) => {} LL | None => {} - | ^^^^ + | ^^^^ unreachable pattern error: unreachable pattern --> $DIR/top-level-alternation.rs:49:9 | LL | None | Some(_) => {} - | ^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^ unreachable pattern + | +note: these patterns collectively make the last one unreachable + --> $DIR/top-level-alternation.rs:49:9 + | +LL | Some(_) => {} + | ------- matches some of the same values +LL | None => {} + | ---- matches some of the same values +LL | None | Some(_) => {} + | ^^^^^^^^^^^^^^ collectively making this unreachable error: unreachable pattern --> $DIR/top-level-alternation.rs:53:9 | +LL | 1 | 2 => {}, + | ----- matches all the values already LL | 1..=2 => {}, - | ^^^^^ + | ^^^^^ unreachable pattern error: unreachable pattern --> $DIR/top-level-alternation.rs:56:14 | LL | let (0 | 0) = 0 else { return }; - | ^ + | - ^ unreachable pattern + | | + | matches all the values already error: aborting due to 11 previous errors diff --git a/tests/ui/privacy/private-in-public-warn.rs b/tests/ui/privacy/private-in-public-warn.rs index 99d318e36be..746b98fbd07 100644 --- a/tests/ui/privacy/private-in-public-warn.rs +++ b/tests/ui/privacy/private-in-public-warn.rs @@ -39,7 +39,7 @@ mod traits { pub trait PubTr {} pub type Alias<T: PrivTr> = T; //~ ERROR trait `traits::PrivTr` is more private than the item `traits::Alias` - //~^ WARNING bounds on generic parameters are not enforced in type aliases + //~^ WARNING bounds on generic parameters in type aliases are not enforced pub trait Tr1: PrivTr {} //~ ERROR trait `traits::PrivTr` is more private than the item `traits::Tr1` pub trait Tr2<T: PrivTr> {} //~ ERROR trait `traits::PrivTr` is more private than the item `traits::Tr2` pub trait Tr3 { @@ -58,7 +58,7 @@ mod traits_where { pub type Alias<T> where T: PrivTr = T; //~^ ERROR trait `traits_where::PrivTr` is more private than the item `traits_where::Alias` - //~| WARNING where clauses are not enforced in type aliases + //~| WARNING where clauses on type aliases are not enforced pub trait Tr2<T> where T: PrivTr {} //~^ ERROR trait `traits_where::PrivTr` is more private than the item `traits_where::Tr2` pub trait Tr3 { diff --git a/tests/ui/privacy/private-in-public-warn.stderr b/tests/ui/privacy/private-in-public-warn.stderr index ac7e5547de9..3f7b8c281e7 100644 --- a/tests/ui/privacy/private-in-public-warn.stderr +++ b/tests/ui/privacy/private-in-public-warn.stderr @@ -395,30 +395,32 @@ note: but type `Priv2` is only usable at visibility `pub(self)` LL | struct Priv2; | ^^^^^^^^^^^^ -warning: bounds on generic parameters are not enforced in type aliases +warning: bounds on generic parameters in type aliases are not enforced --> $DIR/private-in-public-warn.rs:41:23 | LL | pub type Alias<T: PrivTr> = T; - | ^^^^^^ - | + | --^^^^^^ + | | | + | | will not be checked at usage sites of the type alias + | help: remove this bound + | + = note: this is a known limitation of the type checker that may be lifted in a future edition. + see issue #112792 <https://github.com/rust-lang/rust/issues/112792> for more information + = help: add `#![feature(lazy_type_alias)]` to the crate attributes to enable the desired semantics = note: `#[warn(type_alias_bounds)]` on by default -help: the bound will not be checked when the type alias is used, and should be removed - | -LL - pub type Alias<T: PrivTr> = T; -LL + pub type Alias<T> = T; - | -warning: where clauses are not enforced in type aliases +warning: where clauses on type aliases are not enforced --> $DIR/private-in-public-warn.rs:59:29 | LL | pub type Alias<T> where T: PrivTr = T; - | ^^^^^^^^^ - | -help: the clause will not be checked when the type alias is used, and should be removed - | -LL - pub type Alias<T> where T: PrivTr = T; -LL + pub type Alias<T> = T; - | + | ------^^^^^^^^^ + | | | + | | will not be checked at usage sites of the type alias + | help: remove this where clause + | + = note: this is a known limitation of the type checker that may be lifted in a future edition. + see issue #112792 <https://github.com/rust-lang/rust/issues/112792> for more information + = help: add `#![feature(lazy_type_alias)]` to the crate attributes to enable the desired semantics error: aborting due to 34 previous errors; 2 warnings emitted diff --git a/tests/ui/reachable/unreachable-arm.stderr b/tests/ui/reachable/unreachable-arm.stderr index 60db8217640..79627404030 100644 --- a/tests/ui/reachable/unreachable-arm.stderr +++ b/tests/ui/reachable/unreachable-arm.stderr @@ -1,8 +1,10 @@ error: unreachable pattern --> $DIR/unreachable-arm.rs:11:9 | +LL | Foo::B(_) | Foo::A(box _, 1) => { } + | ---------------------------- matches all the values already LL | Foo::A(_, 1) => { } - | ^^^^^^^^^^^^ + | ^^^^^^^^^^^^ unreachable pattern | note: the lint level is defined here --> $DIR/unreachable-arm.rs:4:9 diff --git a/tests/ui/reachable/unreachable-loop-patterns.stderr b/tests/ui/reachable/unreachable-loop-patterns.stderr index 1dea9d813f9..bdd9b5ee411 100644 --- a/tests/ui/reachable/unreachable-loop-patterns.stderr +++ b/tests/ui/reachable/unreachable-loop-patterns.stderr @@ -4,6 +4,7 @@ error: unreachable pattern LL | for _ in unimplemented!() as Void {} | ^ | + = note: this pattern matches no values because `Void` is uninhabited note: the lint level is defined here --> $DIR/unreachable-loop-patterns.rs:5:9 | diff --git a/tests/ui/reachable/unreachable-try-pattern.stderr b/tests/ui/reachable/unreachable-try-pattern.stderr index 8f3e23119fb..bc1a6fffda6 100644 --- a/tests/ui/reachable/unreachable-try-pattern.stderr +++ b/tests/ui/reachable/unreachable-try-pattern.stderr @@ -19,6 +19,7 @@ warning: unreachable pattern LL | let y = (match x { Ok(n) => Ok(n as u32), Err(e) => Err(e) })?; | ^^^^^ | + = note: this pattern matches no values because `!` is uninhabited note: the lint level is defined here --> $DIR/unreachable-try-pattern.rs:4:9 | @@ -30,6 +31,8 @@ warning: unreachable pattern | LL | let y = (match x { Ok(n) => Ok(n), Err(e) => Err(e) })?; | ^^^^^^ + | + = note: this pattern matches no values because `Void` is uninhabited warning: 3 warnings emitted diff --git a/tests/ui/resolve/issue-118295.rs b/tests/ui/resolve/issue-118295.rs index b97681d9563..37a49baee80 100644 --- a/tests/ui/resolve/issue-118295.rs +++ b/tests/ui/resolve/issue-118295.rs @@ -1,5 +1,11 @@ macro_rules! {} //~^ ERROR cannot find macro `macro_rules` in this scope //~| NOTE maybe you have forgotten to define a name for this `macro_rules!` +//~| put a macro name here + +macro_rules!{} +//~^ ERROR cannot find macro `macro_rules` in this scope +//~| NOTE maybe you have forgotten to define a name for this `macro_rules!` +//~| put a macro name here fn main() {} diff --git a/tests/ui/resolve/issue-118295.stderr b/tests/ui/resolve/issue-118295.stderr index d60d7d9185d..06a37e81d6c 100644 --- a/tests/ui/resolve/issue-118295.stderr +++ b/tests/ui/resolve/issue-118295.stderr @@ -1,14 +1,26 @@ error: cannot find macro `macro_rules` in this scope - --> $DIR/issue-118295.rs:1:1 + --> $DIR/issue-118295.rs:6:1 | -LL | macro_rules! {} +LL | macro_rules!{} | ^^^^^^^^^^^ | note: maybe you have forgotten to define a name for this `macro_rules!` + --> $DIR/issue-118295.rs:6:12 + | +LL | macro_rules!{} + | ^ put a macro name here + +error: cannot find macro `macro_rules` in this scope --> $DIR/issue-118295.rs:1:1 | LL | macro_rules! {} | ^^^^^^^^^^^ + | +note: maybe you have forgotten to define a name for this `macro_rules!` + --> $DIR/issue-118295.rs:1:12 + | +LL | macro_rules! {} + | ^ put a macro name here -error: aborting due to 1 previous error +error: aborting due to 2 previous errors diff --git a/tests/ui/resolve/issue-55673.stderr b/tests/ui/resolve/issue-55673.stderr index ffc3252230a..4069b35a998 100644 --- a/tests/ui/resolve/issue-55673.stderr +++ b/tests/ui/resolve/issue-55673.stderr @@ -19,7 +19,7 @@ help: consider further restricting type parameter `T` | LL | T::Baa: std::fmt::Debug, T: Foo | ~~~~~~~~ -help: and also change the associated type name +help: ...and changing the associated type name | LL | T::Bar: std::fmt::Debug, | ~~~ diff --git a/tests/ui/rfcs/rfc-0000-never_patterns/unreachable.exh_pats.stderr b/tests/ui/rfcs/rfc-0000-never_patterns/unreachable.exh_pats.stderr index fe2a72d2a31..a875041d89c 100644 --- a/tests/ui/rfcs/rfc-0000-never_patterns/unreachable.exh_pats.stderr +++ b/tests/ui/rfcs/rfc-0000-never_patterns/unreachable.exh_pats.stderr @@ -4,6 +4,7 @@ error: unreachable pattern LL | Err(!), | ^^^^^^ | + = note: this pattern matches no values because `Void` is uninhabited note: the lint level is defined here --> $DIR/unreachable.rs:7:9 | @@ -15,30 +16,40 @@ error: unreachable pattern | LL | let (Ok(_x) | Err(!)) = res_void; | ^^^^^^ + | + = note: this pattern matches no values because `Void` is uninhabited error: unreachable pattern --> $DIR/unreachable.rs:22:12 | LL | if let Err(!) = res_void {} | ^^^^^^ + | + = note: this pattern matches no values because `Void` is uninhabited error: unreachable pattern --> $DIR/unreachable.rs:24:24 | LL | if let (Ok(true) | Err(!)) = res_void {} | ^^^^^^ + | + = note: this pattern matches no values because `Void` is uninhabited error: unreachable pattern --> $DIR/unreachable.rs:26:23 | LL | for (Ok(mut _x) | Err(!)) in [res_void] {} | ^^^^^^ + | + = note: this pattern matches no values because `Void` is uninhabited error: unreachable pattern --> $DIR/unreachable.rs:30:18 | LL | fn foo((Ok(_x) | Err(!)): Result<bool, Void>) {} | ^^^^^^ + | + = note: this pattern matches no values because `Void` is uninhabited error: aborting due to 6 previous errors diff --git a/tests/ui/rfcs/rfc-2008-non-exhaustive/enum_same_crate_empty_match.stderr b/tests/ui/rfcs/rfc-2008-non-exhaustive/enum_same_crate_empty_match.stderr index 7386f10a6fb..d5f58e436c5 100644 --- a/tests/ui/rfcs/rfc-2008-non-exhaustive/enum_same_crate_empty_match.stderr +++ b/tests/ui/rfcs/rfc-2008-non-exhaustive/enum_same_crate_empty_match.stderr @@ -4,6 +4,7 @@ error: unreachable pattern LL | _ => {} | ^ | + = note: this pattern matches no values because `EmptyNonExhaustiveEnum` is uninhabited note: the lint level is defined here --> $DIR/enum_same_crate_empty_match.rs:1:9 | diff --git a/tests/ui/rfcs/rfc-2008-non-exhaustive/uninhabited/issue-65157-repeated-match-arm.stderr b/tests/ui/rfcs/rfc-2008-non-exhaustive/uninhabited/issue-65157-repeated-match-arm.stderr index 3034a67dc43..4ec4ec9705a 100644 --- a/tests/ui/rfcs/rfc-2008-non-exhaustive/uninhabited/issue-65157-repeated-match-arm.stderr +++ b/tests/ui/rfcs/rfc-2008-non-exhaustive/uninhabited/issue-65157-repeated-match-arm.stderr @@ -2,7 +2,9 @@ error: unreachable pattern --> $DIR/issue-65157-repeated-match-arm.rs:15:9 | LL | PartiallyInhabitedVariants::Struct { .. } => {}, - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ----------------------------------------- matches all the values already +LL | PartiallyInhabitedVariants::Struct { .. } => {}, + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unreachable pattern | note: the lint level is defined here --> $DIR/issue-65157-repeated-match-arm.rs:2:9 diff --git a/tests/ui/rfcs/rfc-2008-non-exhaustive/uninhabited/patterns_same_crate.stderr b/tests/ui/rfcs/rfc-2008-non-exhaustive/uninhabited/patterns_same_crate.stderr index 8bfd6e91f4d..d5192a70ed5 100644 --- a/tests/ui/rfcs/rfc-2008-non-exhaustive/uninhabited/patterns_same_crate.stderr +++ b/tests/ui/rfcs/rfc-2008-non-exhaustive/uninhabited/patterns_same_crate.stderr @@ -4,6 +4,7 @@ error: unreachable pattern LL | Some(_x) => (), | ^^^^^^^^ | + = note: this pattern matches no values because `UninhabitedEnum` is uninhabited note: the lint level is defined here --> $DIR/patterns_same_crate.rs:1:9 | @@ -15,24 +16,32 @@ error: unreachable pattern | LL | Some(_x) => (), | ^^^^^^^^ + | + = note: this pattern matches no values because `UninhabitedVariants` is uninhabited error: unreachable pattern --> $DIR/patterns_same_crate.rs:61:15 | LL | while let PartiallyInhabitedVariants::Struct { x } = partially_inhabited_variant() { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: this pattern matches no values because `!` is uninhabited error: unreachable pattern --> $DIR/patterns_same_crate.rs:65:15 | LL | while let Some(_x) = uninhabited_struct() { | ^^^^^^^^ + | + = note: this pattern matches no values because `UninhabitedStruct` is uninhabited error: unreachable pattern --> $DIR/patterns_same_crate.rs:68:15 | LL | while let Some(_x) = uninhabited_tuple_struct() { | ^^^^^^^^ + | + = note: this pattern matches no values because `UninhabitedTupleStruct` is uninhabited error: aborting due to 5 previous errors diff --git a/tests/ui/rfcs/rfc-2091-track-caller/error-with-naked.rs b/tests/ui/rfcs/rfc-2091-track-caller/error-with-naked.rs index 6eaa7d4d9bc..0c73b9abf35 100644 --- a/tests/ui/rfcs/rfc-2091-track-caller/error-with-naked.rs +++ b/tests/ui/rfcs/rfc-2091-track-caller/error-with-naked.rs @@ -3,7 +3,7 @@ use std::arch::asm; -#[track_caller] //~ ERROR cannot use `#[track_caller]` with `#[naked]` +#[track_caller] //~ ERROR [E0736] //~^ ERROR `#[track_caller]` requires Rust ABI #[naked] extern "C" fn f() { @@ -15,7 +15,7 @@ extern "C" fn f() { struct S; impl S { - #[track_caller] //~ ERROR cannot use `#[track_caller]` with `#[naked]` + #[track_caller] //~ ERROR [E0736] //~^ ERROR `#[track_caller]` requires Rust ABI #[naked] extern "C" fn g() { diff --git a/tests/ui/rfcs/rfc-2091-track-caller/error-with-naked.stderr b/tests/ui/rfcs/rfc-2091-track-caller/error-with-naked.stderr index 04c5c649d7f..0625ed1183b 100644 --- a/tests/ui/rfcs/rfc-2091-track-caller/error-with-naked.stderr +++ b/tests/ui/rfcs/rfc-2091-track-caller/error-with-naked.stderr @@ -1,14 +1,20 @@ -error[E0736]: cannot use `#[track_caller]` with `#[naked]` +error[E0736]: attribute incompatible with `#[naked]` --> $DIR/error-with-naked.rs:6:1 | LL | #[track_caller] - | ^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^ the `track_caller` attribute is incompatible with `#[naked]` +LL | +LL | #[naked] + | -------- function marked with `#[naked]` here -error[E0736]: cannot use `#[track_caller]` with `#[naked]` +error[E0736]: attribute incompatible with `#[naked]` --> $DIR/error-with-naked.rs:18:5 | LL | #[track_caller] - | ^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^ the `track_caller` attribute is incompatible with `#[naked]` +LL | +LL | #[naked] + | -------- function marked with `#[naked]` here error[E0737]: `#[track_caller]` requires Rust ABI --> $DIR/error-with-naked.rs:6:1 diff --git a/tests/ui/rfcs/rfc-2294-if-let-guard/warns.stderr b/tests/ui/rfcs/rfc-2294-if-let-guard/warns.stderr index eed5dbb88de..8d0874fa900 100644 --- a/tests/ui/rfcs/rfc-2294-if-let-guard/warns.stderr +++ b/tests/ui/rfcs/rfc-2294-if-let-guard/warns.stderr @@ -16,7 +16,9 @@ error: unreachable pattern --> $DIR/warns.rs:15:25 | LL | x if let None | None = x => {} - | ^^^^ + | ---- ^^^^ unreachable pattern + | | + | matches all the values already | note: the lint level is defined here --> $DIR/warns.rs:12:8 diff --git a/tests/ui/rust-2024/prelude-migration/future-poll-already-future.rs b/tests/ui/rust-2024/prelude-migration/future-poll-already-future.rs new file mode 100644 index 00000000000..7bf5118c340 --- /dev/null +++ b/tests/ui/rust-2024/prelude-migration/future-poll-already-future.rs @@ -0,0 +1,17 @@ +//@ revisions: e2021 e2024 +//@[e2021] edition: 2021 +//@[e2024] edition: 2024 +//@[e2024] compile-flags: -Zunstable-options +//@ check-pass + +#![deny(rust_2024_prelude_collisions)] + +use std::future::Future; + +fn main() { + core::pin::pin!(async {}).poll(&mut context()); +} + +fn context() -> core::task::Context<'static> { + loop {} +} diff --git a/tests/ui/rust-2024/prelude-migration/future-poll-async-block.e2021.fixed b/tests/ui/rust-2024/prelude-migration/future-poll-async-block.e2021.fixed new file mode 100644 index 00000000000..44850c8c45b --- /dev/null +++ b/tests/ui/rust-2024/prelude-migration/future-poll-async-block.e2021.fixed @@ -0,0 +1,21 @@ +//@ revisions: e2021 e2024 +//@[e2021] edition: 2021 +//@[e2021] run-rustfix +//@[e2024] edition: 2024 +//@[e2024] compile-flags: -Zunstable-options +//@[e2024] check-pass + +#![deny(rust_2024_prelude_collisions)] +trait Meow { + fn poll(&self, _ctx: &mut core::task::Context<'_>) {} +} +impl<T> Meow for T {} +fn main() { + Meow::poll(&core::pin::pin!(async {}), &mut context()); + //[e2021]~^ ERROR trait method `poll` will become ambiguous in Rust 2024 + //[e2021]~| WARN this is accepted in the current edition (Rust 2021) but is a hard error in Rust 2024! +} + +fn context() -> core::task::Context<'static> { + loop {} +} diff --git a/tests/ui/rust-2024/prelude-migration/future-poll-async-block.e2021.stderr b/tests/ui/rust-2024/prelude-migration/future-poll-async-block.e2021.stderr new file mode 100644 index 00000000000..496b3197c34 --- /dev/null +++ b/tests/ui/rust-2024/prelude-migration/future-poll-async-block.e2021.stderr @@ -0,0 +1,16 @@ +error: trait method `poll` will become ambiguous in Rust 2024 + --> $DIR/future-poll-async-block.rs:14:5 + | +LL | core::pin::pin!(async {}).poll(&mut context()); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: disambiguate the associated function: `Meow::poll(&core::pin::pin!(async {}), &mut context())` + | + = warning: this is accepted in the current edition (Rust 2021) but is a hard error in Rust 2024! + = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/prelude.html> +note: the lint level is defined here + --> $DIR/future-poll-async-block.rs:8:9 + | +LL | #![deny(rust_2024_prelude_collisions)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 1 previous error + diff --git a/tests/ui/rust-2024/prelude-migration/future-poll-async-block.rs b/tests/ui/rust-2024/prelude-migration/future-poll-async-block.rs new file mode 100644 index 00000000000..614e4c786c5 --- /dev/null +++ b/tests/ui/rust-2024/prelude-migration/future-poll-async-block.rs @@ -0,0 +1,21 @@ +//@ revisions: e2021 e2024 +//@[e2021] edition: 2021 +//@[e2021] run-rustfix +//@[e2024] edition: 2024 +//@[e2024] compile-flags: -Zunstable-options +//@[e2024] check-pass + +#![deny(rust_2024_prelude_collisions)] +trait Meow { + fn poll(&self, _ctx: &mut core::task::Context<'_>) {} +} +impl<T> Meow for T {} +fn main() { + core::pin::pin!(async {}).poll(&mut context()); + //[e2021]~^ ERROR trait method `poll` will become ambiguous in Rust 2024 + //[e2021]~| WARN this is accepted in the current edition (Rust 2021) but is a hard error in Rust 2024! +} + +fn context() -> core::task::Context<'static> { + loop {} +} diff --git a/tests/ui/rust-2024/prelude-migration/future-poll-not-future-pinned.e2021.fixed b/tests/ui/rust-2024/prelude-migration/future-poll-not-future-pinned.e2021.fixed new file mode 100644 index 00000000000..c96d1dcecc2 --- /dev/null +++ b/tests/ui/rust-2024/prelude-migration/future-poll-not-future-pinned.e2021.fixed @@ -0,0 +1,21 @@ +//@ revisions: e2021 e2024 +//@[e2021] edition: 2021 +//@[e2021] run-rustfix +//@[e2024] edition: 2024 +//@[e2024] compile-flags: -Zunstable-options +//@[e2024] check-pass + +#![deny(rust_2024_prelude_collisions)] +trait Meow { + fn poll(&self) {} +} +impl<T> Meow for T {} +fn main() { + // This is a deliberate false positive. + // While `()` does not implement `Future` and can therefore not be ambiguous, we + // do not check that in the lint, as that introduces additional complexities. + // Just checking whether the self type is `Pin<&mut _>` is enough. + Meow::poll(&core::pin::pin!(())); + //[e2021]~^ ERROR trait method `poll` will become ambiguous in Rust 2024 + //[e2021]~| WARN this is accepted in the current edition (Rust 2021) but is a hard error in Rust 2024! +} diff --git a/tests/ui/rust-2024/prelude-migration/future-poll-not-future-pinned.e2021.stderr b/tests/ui/rust-2024/prelude-migration/future-poll-not-future-pinned.e2021.stderr new file mode 100644 index 00000000000..020a00ccdec --- /dev/null +++ b/tests/ui/rust-2024/prelude-migration/future-poll-not-future-pinned.e2021.stderr @@ -0,0 +1,16 @@ +error: trait method `poll` will become ambiguous in Rust 2024 + --> $DIR/future-poll-not-future-pinned.rs:18:5 + | +LL | core::pin::pin!(()).poll(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: disambiguate the associated function: `Meow::poll(&core::pin::pin!(()))` + | + = warning: this is accepted in the current edition (Rust 2021) but is a hard error in Rust 2024! + = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/prelude.html> +note: the lint level is defined here + --> $DIR/future-poll-not-future-pinned.rs:8:9 + | +LL | #![deny(rust_2024_prelude_collisions)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 1 previous error + diff --git a/tests/ui/rust-2024/prelude-migration/future-poll-not-future-pinned.rs b/tests/ui/rust-2024/prelude-migration/future-poll-not-future-pinned.rs new file mode 100644 index 00000000000..21b170a5f1d --- /dev/null +++ b/tests/ui/rust-2024/prelude-migration/future-poll-not-future-pinned.rs @@ -0,0 +1,21 @@ +//@ revisions: e2021 e2024 +//@[e2021] edition: 2021 +//@[e2021] run-rustfix +//@[e2024] edition: 2024 +//@[e2024] compile-flags: -Zunstable-options +//@[e2024] check-pass + +#![deny(rust_2024_prelude_collisions)] +trait Meow { + fn poll(&self) {} +} +impl<T> Meow for T {} +fn main() { + // This is a deliberate false positive. + // While `()` does not implement `Future` and can therefore not be ambiguous, we + // do not check that in the lint, as that introduces additional complexities. + // Just checking whether the self type is `Pin<&mut _>` is enough. + core::pin::pin!(()).poll(); + //[e2021]~^ ERROR trait method `poll` will become ambiguous in Rust 2024 + //[e2021]~| WARN this is accepted in the current edition (Rust 2021) but is a hard error in Rust 2024! +} diff --git a/tests/ui/rust-2024/prelude-migration/future-poll-not-future.rs b/tests/ui/rust-2024/prelude-migration/future-poll-not-future.rs new file mode 100644 index 00000000000..899b69ebfc2 --- /dev/null +++ b/tests/ui/rust-2024/prelude-migration/future-poll-not-future.rs @@ -0,0 +1,15 @@ +//@ revisions: e2021 e2024 +//@[e2021] edition: 2021 +//@[e2024] edition: 2024 +//@[e2024] compile-flags: -Zunstable-options +//@ check-pass + +#![deny(rust_2024_prelude_collisions)] +trait Meow { + fn poll(&self) {} +} +impl<T> Meow for T {} +fn main() { + // As the self type here is not `Pin<&mut _>`, the lint does not fire. + ().poll(); +} diff --git a/tests/ui/rust-2024/prelude-migration/in_2024_compatibility.rs b/tests/ui/rust-2024/prelude-migration/in_2024_compatibility.rs new file mode 100644 index 00000000000..b6a5d278720 --- /dev/null +++ b/tests/ui/rust-2024/prelude-migration/in_2024_compatibility.rs @@ -0,0 +1,17 @@ +//@ edition: 2021 + +#![deny(rust_2024_compatibility)] + +trait Meow { + fn poll(&self, _ctx: &mut core::task::Context<'_>) {} +} +impl<T> Meow for T {} +fn main() { + core::pin::pin!(async {}).poll(&mut context()); + //~^ ERROR trait method `poll` will become ambiguous in Rust 2024 + //~| WARN this is accepted in the current edition (Rust 2021) but is a hard error in Rust 2024! +} + +fn context() -> core::task::Context<'static> { + loop {} +} diff --git a/tests/ui/rust-2024/prelude-migration/in_2024_compatibility.stderr b/tests/ui/rust-2024/prelude-migration/in_2024_compatibility.stderr new file mode 100644 index 00000000000..5865029d65d --- /dev/null +++ b/tests/ui/rust-2024/prelude-migration/in_2024_compatibility.stderr @@ -0,0 +1,17 @@ +error: trait method `poll` will become ambiguous in Rust 2024 + --> $DIR/in_2024_compatibility.rs:10:5 + | +LL | core::pin::pin!(async {}).poll(&mut context()); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: disambiguate the associated function: `Meow::poll(&core::pin::pin!(async {}), &mut context())` + | + = warning: this is accepted in the current edition (Rust 2021) but is a hard error in Rust 2024! + = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/prelude.html> +note: the lint level is defined here + --> $DIR/in_2024_compatibility.rs:3:9 + | +LL | #![deny(rust_2024_compatibility)] + | ^^^^^^^^^^^^^^^^^^^^^^^ + = note: `#[deny(rust_2024_prelude_collisions)]` implied by `#[deny(rust_2024_compatibility)]` + +error: aborting due to 1 previous error + diff --git a/tests/ui/rust-2024/prelude-migration/into-future-adt.e2021.fixed b/tests/ui/rust-2024/prelude-migration/into-future-adt.e2021.fixed new file mode 100644 index 00000000000..0b0873eb238 --- /dev/null +++ b/tests/ui/rust-2024/prelude-migration/into-future-adt.e2021.fixed @@ -0,0 +1,29 @@ +//@ revisions: e2021 e2024 +//@[e2021] edition: 2021 +//@[e2021] run-rustfix +//@[e2024] edition: 2024 +//@[e2024] compile-flags: -Zunstable-options +//@[e2024] check-pass + +#![deny(rust_2024_prelude_collisions)] +trait Meow { + fn into_future(&self) {} +} +impl Meow for Cat {} + +struct Cat; + +impl core::future::IntoFuture for Cat { + type Output = (); + type IntoFuture = core::future::Ready<()>; + + fn into_future(self) -> Self::IntoFuture { + core::future::ready(()) + } +} + +fn main() { + Meow::into_future(&Cat); + //[e2021]~^ ERROR trait method `into_future` will become ambiguous in Rust 2024 + //[e2021]~| WARN this is accepted in the current edition (Rust 2021) but is a hard error in Rust 2024! +} diff --git a/tests/ui/rust-2024/prelude-migration/into-future-adt.e2021.stderr b/tests/ui/rust-2024/prelude-migration/into-future-adt.e2021.stderr new file mode 100644 index 00000000000..b74e80e2a4a --- /dev/null +++ b/tests/ui/rust-2024/prelude-migration/into-future-adt.e2021.stderr @@ -0,0 +1,16 @@ +error: trait method `into_future` will become ambiguous in Rust 2024 + --> $DIR/into-future-adt.rs:26:5 + | +LL | Cat.into_future(); + | ^^^^^^^^^^^^^^^^^ help: disambiguate the associated function: `Meow::into_future(&Cat)` + | + = warning: this is accepted in the current edition (Rust 2021) but is a hard error in Rust 2024! + = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/prelude.html> +note: the lint level is defined here + --> $DIR/into-future-adt.rs:8:9 + | +LL | #![deny(rust_2024_prelude_collisions)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 1 previous error + diff --git a/tests/ui/rust-2024/prelude-migration/into-future-adt.rs b/tests/ui/rust-2024/prelude-migration/into-future-adt.rs new file mode 100644 index 00000000000..0db70930bc7 --- /dev/null +++ b/tests/ui/rust-2024/prelude-migration/into-future-adt.rs @@ -0,0 +1,29 @@ +//@ revisions: e2021 e2024 +//@[e2021] edition: 2021 +//@[e2021] run-rustfix +//@[e2024] edition: 2024 +//@[e2024] compile-flags: -Zunstable-options +//@[e2024] check-pass + +#![deny(rust_2024_prelude_collisions)] +trait Meow { + fn into_future(&self) {} +} +impl Meow for Cat {} + +struct Cat; + +impl core::future::IntoFuture for Cat { + type Output = (); + type IntoFuture = core::future::Ready<()>; + + fn into_future(self) -> Self::IntoFuture { + core::future::ready(()) + } +} + +fn main() { + Cat.into_future(); + //[e2021]~^ ERROR trait method `into_future` will become ambiguous in Rust 2024 + //[e2021]~| WARN this is accepted in the current edition (Rust 2021) but is a hard error in Rust 2024! +} diff --git a/tests/ui/rust-2024/prelude-migration/into-future-already-into-future.rs b/tests/ui/rust-2024/prelude-migration/into-future-already-into-future.rs new file mode 100644 index 00000000000..6bc2ea31705 --- /dev/null +++ b/tests/ui/rust-2024/prelude-migration/into-future-already-into-future.rs @@ -0,0 +1,24 @@ +//@ revisions: e2021 e2024 +//@[e2021] edition: 2021 +//@[e2024] edition: 2024 +//@[e2024] compile-flags: -Zunstable-options +//@ check-pass + +#![deny(rust_2024_prelude_collisions)] + +use core::future::IntoFuture; + +struct Cat; + +impl IntoFuture for Cat { + type Output = (); + type IntoFuture = core::future::Ready<()>; + + fn into_future(self) -> Self::IntoFuture { + core::future::ready(()) + } +} + +fn main() { + let _ = Cat.into_future(); +} diff --git a/tests/ui/rust-2024/prelude-migration/into-future-not-into-future.e2021.fixed b/tests/ui/rust-2024/prelude-migration/into-future-not-into-future.e2021.fixed new file mode 100644 index 00000000000..a798014d93d --- /dev/null +++ b/tests/ui/rust-2024/prelude-migration/into-future-not-into-future.e2021.fixed @@ -0,0 +1,23 @@ +//@ revisions: e2021 e2024 +//@[e2021] edition: 2021 +//@[e2021] run-rustfix +//@[e2024] edition: 2024 +//@[e2024] compile-flags: -Zunstable-options +//@[e2024] check-pass + +#![deny(rust_2024_prelude_collisions)] +trait Meow { + fn into_future(&self) {} +} +impl Meow for Cat {} + +struct Cat; + +fn main() { + // This is a false positive, but it should be rare enough to not matter, and checking whether + // it implements the trait can have other nontrivial consequences, so it was decided to accept + // this. + Meow::into_future(&Cat); + //[e2021]~^ ERROR trait method `into_future` will become ambiguous in Rust 2024 + //[e2021]~| WARN this is accepted in the current edition (Rust 2021) but is a hard error in Rust 2024! +} diff --git a/tests/ui/rust-2024/prelude-migration/into-future-not-into-future.e2021.stderr b/tests/ui/rust-2024/prelude-migration/into-future-not-into-future.e2021.stderr new file mode 100644 index 00000000000..6ea4580ca72 --- /dev/null +++ b/tests/ui/rust-2024/prelude-migration/into-future-not-into-future.e2021.stderr @@ -0,0 +1,16 @@ +error: trait method `into_future` will become ambiguous in Rust 2024 + --> $DIR/into-future-not-into-future.rs:20:5 + | +LL | Cat.into_future(); + | ^^^^^^^^^^^^^^^^^ help: disambiguate the associated function: `Meow::into_future(&Cat)` + | + = warning: this is accepted in the current edition (Rust 2021) but is a hard error in Rust 2024! + = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/prelude.html> +note: the lint level is defined here + --> $DIR/into-future-not-into-future.rs:8:9 + | +LL | #![deny(rust_2024_prelude_collisions)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 1 previous error + diff --git a/tests/ui/rust-2024/prelude-migration/into-future-not-into-future.rs b/tests/ui/rust-2024/prelude-migration/into-future-not-into-future.rs new file mode 100644 index 00000000000..23e81cfe6b4 --- /dev/null +++ b/tests/ui/rust-2024/prelude-migration/into-future-not-into-future.rs @@ -0,0 +1,23 @@ +//@ revisions: e2021 e2024 +//@[e2021] edition: 2021 +//@[e2021] run-rustfix +//@[e2024] edition: 2024 +//@[e2024] compile-flags: -Zunstable-options +//@[e2024] check-pass + +#![deny(rust_2024_prelude_collisions)] +trait Meow { + fn into_future(&self) {} +} +impl Meow for Cat {} + +struct Cat; + +fn main() { + // This is a false positive, but it should be rare enough to not matter, and checking whether + // it implements the trait can have other nontrivial consequences, so it was decided to accept + // this. + Cat.into_future(); + //[e2021]~^ ERROR trait method `into_future` will become ambiguous in Rust 2024 + //[e2021]~| WARN this is accepted in the current edition (Rust 2021) but is a hard error in Rust 2024! +} diff --git a/tests/ui/traits/maybe-polarity-pass.rs b/tests/ui/traits/maybe-polarity-pass.rs new file mode 100644 index 00000000000..075a0d8dcac --- /dev/null +++ b/tests/ui/traits/maybe-polarity-pass.rs @@ -0,0 +1,27 @@ +//@ check-pass + +#![feature(auto_traits)] +#![feature(more_maybe_bounds)] +#![feature(negative_impls)] + +trait Trait1 {} +auto trait Trait2 {} + +trait Trait3 : ?Trait1 {} +trait Trait4 where Self: Trait1 {} + +fn foo(_: Box<(dyn Trait3 + ?Trait2)>) {} +fn bar<T: ?Sized + ?Trait2 + ?Trait1 + ?Trait4>(_: &T) {} +//~^ WARN relaxing a default bound only does something for `?Sized`; all other traits are not bound by default +//~| WARN relaxing a default bound only does something for `?Sized`; all other traits are not bound by default +//~| WARN relaxing a default bound only does something for `?Sized`; all other traits are not bound by default + +struct S; +impl !Trait2 for S {} +impl Trait1 for S {} +impl Trait3 for S {} + +fn main() { + foo(Box::new(S)); + bar(&S); +} diff --git a/tests/ui/traits/maybe-polarity-pass.stderr b/tests/ui/traits/maybe-polarity-pass.stderr new file mode 100644 index 00000000000..09ed52f5b0d --- /dev/null +++ b/tests/ui/traits/maybe-polarity-pass.stderr @@ -0,0 +1,20 @@ +warning: relaxing a default bound only does something for `?Sized`; all other traits are not bound by default + --> $DIR/maybe-polarity-pass.rs:14:20 + | +LL | fn bar<T: ?Sized + ?Trait2 + ?Trait1 + ?Trait4>(_: &T) {} + | ^^^^^^^ + +warning: relaxing a default bound only does something for `?Sized`; all other traits are not bound by default + --> $DIR/maybe-polarity-pass.rs:14:30 + | +LL | fn bar<T: ?Sized + ?Trait2 + ?Trait1 + ?Trait4>(_: &T) {} + | ^^^^^^^ + +warning: relaxing a default bound only does something for `?Sized`; all other traits are not bound by default + --> $DIR/maybe-polarity-pass.rs:14:40 + | +LL | fn bar<T: ?Sized + ?Trait2 + ?Trait1 + ?Trait4>(_: &T) {} + | ^^^^^^^ + +warning: 3 warnings emitted + diff --git a/tests/ui/traits/maybe-polarity-repeated.rs b/tests/ui/traits/maybe-polarity-repeated.rs new file mode 100644 index 00000000000..4b5ec83fffa --- /dev/null +++ b/tests/ui/traits/maybe-polarity-repeated.rs @@ -0,0 +1,9 @@ +#![feature(more_maybe_bounds)] + +trait Trait {} +fn foo<T: ?Trait + ?Trait>(_: T) {} +//~^ ERROR type parameter has more than one relaxed default bound, only one is supported +//~| WARN relaxing a default bound only does something for `?Sized`; all other traits are not bound by default +//~| WARN relaxing a default bound only does something for `?Sized`; all other traits are not bound by default + +fn main() {} diff --git a/tests/ui/traits/maybe-polarity-repeated.stderr b/tests/ui/traits/maybe-polarity-repeated.stderr new file mode 100644 index 00000000000..610c484fbec --- /dev/null +++ b/tests/ui/traits/maybe-polarity-repeated.stderr @@ -0,0 +1,21 @@ +error[E0203]: type parameter has more than one relaxed default bound, only one is supported + --> $DIR/maybe-polarity-repeated.rs:4:11 + | +LL | fn foo<T: ?Trait + ?Trait>(_: T) {} + | ^^^^^^ ^^^^^^ + +warning: relaxing a default bound only does something for `?Sized`; all other traits are not bound by default + --> $DIR/maybe-polarity-repeated.rs:4:11 + | +LL | fn foo<T: ?Trait + ?Trait>(_: T) {} + | ^^^^^^ + +warning: relaxing a default bound only does something for `?Sized`; all other traits are not bound by default + --> $DIR/maybe-polarity-repeated.rs:4:20 + | +LL | fn foo<T: ?Trait + ?Trait>(_: T) {} + | ^^^^^^ + +error: aborting due to 1 previous error; 2 warnings emitted + +For more information about this error, try `rustc --explain E0203`. diff --git a/tests/ui/traits/wf-object/maybe-bound.stderr b/tests/ui/traits/wf-object/maybe-bound.stderr index 2fe3f0fc39f..be7afabd0d0 100644 --- a/tests/ui/traits/wf-object/maybe-bound.stderr +++ b/tests/ui/traits/wf-object/maybe-bound.stderr @@ -1,32 +1,48 @@ -error: `?Trait` is not permitted in trait object types +error[E0658]: `?Trait` is not permitted in trait object types --> $DIR/maybe-bound.rs:5:15 | LL | type _0 = dyn ?Sized + Foo; | ^^^^^^ + | + = help: add `#![feature(more_maybe_bounds)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date -error: `?Trait` is not permitted in trait object types +error[E0658]: `?Trait` is not permitted in trait object types --> $DIR/maybe-bound.rs:8:21 | LL | type _1 = dyn Foo + ?Sized; | ^^^^^^ + | + = help: add `#![feature(more_maybe_bounds)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date -error: `?Trait` is not permitted in trait object types +error[E0658]: `?Trait` is not permitted in trait object types --> $DIR/maybe-bound.rs:11:21 | LL | type _2 = dyn Foo + ?Sized + ?Sized; | ^^^^^^ + | + = help: add `#![feature(more_maybe_bounds)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date -error: `?Trait` is not permitted in trait object types +error[E0658]: `?Trait` is not permitted in trait object types --> $DIR/maybe-bound.rs:11:30 | LL | type _2 = dyn Foo + ?Sized + ?Sized; | ^^^^^^ + | + = help: add `#![feature(more_maybe_bounds)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date -error: `?Trait` is not permitted in trait object types +error[E0658]: `?Trait` is not permitted in trait object types --> $DIR/maybe-bound.rs:15:15 | LL | type _3 = dyn ?Sized + Foo; | ^^^^^^ + | + = help: add `#![feature(more_maybe_bounds)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error: aborting due to 5 previous errors +For more information about this error, try `rustc --explain E0658`. diff --git a/tests/ui/traits/wf-object/only-maybe-bound.stderr b/tests/ui/traits/wf-object/only-maybe-bound.stderr index cbc41feec1e..26269476eaa 100644 --- a/tests/ui/traits/wf-object/only-maybe-bound.stderr +++ b/tests/ui/traits/wf-object/only-maybe-bound.stderr @@ -1,8 +1,11 @@ -error: `?Trait` is not permitted in trait object types +error[E0658]: `?Trait` is not permitted in trait object types --> $DIR/only-maybe-bound.rs:3:15 | LL | type _0 = dyn ?Sized; | ^^^^^^ + | + = help: add `#![feature(more_maybe_bounds)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0224]: at least one trait is required for an object type --> $DIR/only-maybe-bound.rs:3:11 @@ -12,4 +15,5 @@ LL | type _0 = dyn ?Sized; error: aborting due to 2 previous errors -For more information about this error, try `rustc --explain E0224`. +Some errors have detailed explanations: E0224, E0658. +For more information about an error, try `rustc --explain E0224`. diff --git a/tests/ui/trivial-bounds/trivial-bounds-inconsistent.stderr b/tests/ui/trivial-bounds/trivial-bounds-inconsistent.stderr index d66e468873b..0eae68bfcf0 100644 --- a/tests/ui/trivial-bounds/trivial-bounds-inconsistent.stderr +++ b/tests/ui/trivial-bounds/trivial-bounds-inconsistent.stderr @@ -24,18 +24,19 @@ warning: trait bound i32: Foo does not depend on any type or lifetime parameters LL | union U where i32: Foo { f: i32 } | ^^^ -warning: where clauses are not enforced in type aliases +warning: where clauses on type aliases are not enforced --> $DIR/trivial-bounds-inconsistent.rs:22:14 | LL | type Y where i32: Foo = (); - | ^^^^^^^^ - | + | ------^^^^^^^^ + | | | + | | will not be checked at usage sites of the type alias + | help: remove this where clause + | + = note: this is a known limitation of the type checker that may be lifted in a future edition. + see issue #112792 <https://github.com/rust-lang/rust/issues/112792> for more information + = help: add `#![feature(lazy_type_alias)]` to the crate attributes to enable the desired semantics = note: `#[warn(type_alias_bounds)]` on by default -help: the clause will not be checked when the type alias is used, and should be removed - | -LL - type Y where i32: Foo = (); -LL + type Y = (); - | warning: trait bound i32: Foo does not depend on any type or lifetime parameters --> $DIR/trivial-bounds-inconsistent.rs:22:19 diff --git a/tests/ui/type-alias/unresolved-assoc-ty-suggest-trait.eager.stderr b/tests/ui/type-alias/unresolved-assoc-ty-suggest-trait.eager.stderr new file mode 100644 index 00000000000..e891ff10fda --- /dev/null +++ b/tests/ui/type-alias/unresolved-assoc-ty-suggest-trait.eager.stderr @@ -0,0 +1,36 @@ +error[E0220]: associated type `Assoc` not found for `T` + --> $DIR/unresolved-assoc-ty-suggest-trait.rs:9:22 + | +LL | type AssocOf<T> = T::Assoc; + | ^^^^^ there is an associated type `Assoc` in the trait `Trait` + | +help: consider fully qualifying the associated type + | +LL | type AssocOf<T> = <T as Trait>::Assoc; + | + +++++++++ + +error[E0220]: associated type `Assok` not found for `T` + --> $DIR/unresolved-assoc-ty-suggest-trait.rs:13:22 + | +LL | type AssokOf<T> = T::Assok; + | ^^^^^ there is a similarly named associated type `Assoc` in the trait `Trait` + | +help: consider fully qualifying and renaming the associated type + | +LL | type AssokOf<T> = <T as Trait>::Assoc; + | + +++++++++ ~~~~~ + +error[E0220]: associated type `Proj` not found for `T` + --> $DIR/unresolved-assoc-ty-suggest-trait.rs:22:21 + | +LL | type ProjOf<T> = T::Proj; + | ^^^^ there is an associated type `Proj` in the trait `Parametrized` + | +help: consider fully qualifying the associated type + | +LL | type ProjOf<T> = <T as Parametrized</* 'a, T, N */>>::Proj; + | + ++++++++++++++++++++++++++++++++ + +error: aborting due to 3 previous errors + +For more information about this error, try `rustc --explain E0220`. diff --git a/tests/ui/type-alias/unresolved-assoc-ty-suggest-trait.lazy.stderr b/tests/ui/type-alias/unresolved-assoc-ty-suggest-trait.lazy.stderr new file mode 100644 index 00000000000..96179a7b484 --- /dev/null +++ b/tests/ui/type-alias/unresolved-assoc-ty-suggest-trait.lazy.stderr @@ -0,0 +1,40 @@ +error[E0220]: associated type `Assoc` not found for `T` + --> $DIR/unresolved-assoc-ty-suggest-trait.rs:9:22 + | +LL | type AssocOf<T> = T::Assoc; + | ^^^^^ there is an associated type `Assoc` in the trait `Trait` + | +help: consider restricting type parameter `T` + | +LL | type AssocOf<T: Trait> = T::Assoc; + | +++++++ + +error[E0220]: associated type `Assok` not found for `T` + --> $DIR/unresolved-assoc-ty-suggest-trait.rs:13:22 + | +LL | type AssokOf<T> = T::Assok; + | ^^^^^ there is a similarly named associated type `Assoc` in the trait `Trait` + | +help: consider restricting type parameter `T` + | +LL | type AssokOf<T: Trait> = T::Assok; + | +++++++ +help: ...and changing the associated type name + | +LL | type AssokOf<T> = T::Assoc; + | ~~~~~ + +error[E0220]: associated type `Proj` not found for `T` + --> $DIR/unresolved-assoc-ty-suggest-trait.rs:22:21 + | +LL | type ProjOf<T> = T::Proj; + | ^^^^ there is an associated type `Proj` in the trait `Parametrized` + | +help: consider restricting type parameter `T` + | +LL | type ProjOf<T: Parametrized</* 'a, T, N */>> = T::Proj; + | ++++++++++++++++++++++++++++++ + +error: aborting due to 3 previous errors + +For more information about this error, try `rustc --explain E0220`. diff --git a/tests/ui/type-alias/unresolved-assoc-ty-suggest-trait.rs b/tests/ui/type-alias/unresolved-assoc-ty-suggest-trait.rs new file mode 100644 index 00000000000..2c8d448f308 --- /dev/null +++ b/tests/ui/type-alias/unresolved-assoc-ty-suggest-trait.rs @@ -0,0 +1,26 @@ +// Ensure that we don't suggest *type alias bounds* for **eager** type aliases. +// issue: rust-lang/rust#125789 + +//@ revisions: eager lazy +#![cfg_attr(lazy, feature(lazy_type_alias), allow(incomplete_features))] + +trait Trait { type Assoc; } + +type AssocOf<T> = T::Assoc; //~ ERROR associated type `Assoc` not found for `T` +//[eager]~^ HELP consider fully qualifying the associated type +//[lazy]~| HELP consider restricting type parameter `T` + +type AssokOf<T> = T::Assok; //~ ERROR associated type `Assok` not found for `T` +//[eager]~^ HELP consider fully qualifying and renaming the associated type +//[lazy]~| HELP consider restricting type parameter `T` +//[lazy]~| HELP and changing the associated type name + +trait Parametrized<'a, T, const N: usize> { + type Proj; +} + +type ProjOf<T> = T::Proj; //~ ERROR associated type `Proj` not found for `T` +//[eager]~^ HELP consider fully qualifying the associated type +//[lazy]~| HELP consider restricting type parameter `T` + +fn main() {} diff --git a/tests/ui/type/issue-67690-type-alias-bound-diagnostic-crash.rs b/tests/ui/type/issue-67690-type-alias-bound-diagnostic-crash.rs index 5ee3c027f40..52e0887175d 100644 --- a/tests/ui/type/issue-67690-type-alias-bound-diagnostic-crash.rs +++ b/tests/ui/type/issue-67690-type-alias-bound-diagnostic-crash.rs @@ -3,6 +3,6 @@ //@ check-pass pub type T<P: Send + Send + Send> = P; -//~^ WARN bounds on generic parameters are not enforced in type aliases +//~^ WARN bounds on generic parameters in type aliases are not enforced fn main() {} diff --git a/tests/ui/type/issue-67690-type-alias-bound-diagnostic-crash.stderr b/tests/ui/type/issue-67690-type-alias-bound-diagnostic-crash.stderr index 125ffbbb417..9fd0fe4913b 100644 --- a/tests/ui/type/issue-67690-type-alias-bound-diagnostic-crash.stderr +++ b/tests/ui/type/issue-67690-type-alias-bound-diagnostic-crash.stderr @@ -1,15 +1,16 @@ -warning: bounds on generic parameters are not enforced in type aliases +warning: bounds on generic parameters in type aliases are not enforced --> $DIR/issue-67690-type-alias-bound-diagnostic-crash.rs:5:15 | LL | pub type T<P: Send + Send + Send> = P; - | ^^^^ ^^^^ ^^^^ + | --^^^^---^^^^---^^^^ + | | | + | | will not be checked at usage sites of the type alias + | help: remove this bound | + = note: this is a known limitation of the type checker that may be lifted in a future edition. + see issue #112792 <https://github.com/rust-lang/rust/issues/112792> for more information + = help: add `#![feature(lazy_type_alias)]` to the crate attributes to enable the desired semantics = note: `#[warn(type_alias_bounds)]` on by default -help: the bound will not be checked when the type alias is used, and should be removed - | -LL - pub type T<P: Send + Send + Send> = P; -LL + pub type T<P> = P; - | warning: 1 warning emitted diff --git a/tests/ui/type/type-alias-bounds.rs b/tests/ui/type/type-alias-bounds.rs index 6d63c0c7e1b..37c073fe1f9 100644 --- a/tests/ui/type/type-alias-bounds.rs +++ b/tests/ui/type/type-alias-bounds.rs @@ -6,15 +6,15 @@ use std::rc::Rc; type SVec<T: Send + Send> = Vec<T>; -//~^ WARN bounds on generic parameters are not enforced in type aliases [type_alias_bounds] +//~^ WARN bounds on generic parameters in type aliases are not enforced [type_alias_bounds] type S2Vec<T> where T: Send = Vec<T>; -//~^ WARN where clauses are not enforced in type aliases [type_alias_bounds] +//~^ WARN where clauses on type aliases are not enforced [type_alias_bounds] type VVec<'b, 'a: 'b + 'b> = (&'b u32, Vec<&'a i32>); -//~^ WARN bounds on generic parameters are not enforced in type aliases [type_alias_bounds] +//~^ WARN bounds on generic parameters in type aliases are not enforced [type_alias_bounds] type WVec<'b, T: 'b + 'b> = (&'b u32, Vec<T>); -//~^ WARN bounds on generic parameters are not enforced in type aliases [type_alias_bounds] +//~^ WARN bounds on generic parameters in type aliases are not enforced [type_alias_bounds] type W2Vec<'b, T> where T: 'b, T: 'b = (&'b u32, Vec<T>); -//~^ WARN where clauses are not enforced in type aliases [type_alias_bounds] +//~^ WARN where clauses on type aliases are not enforced [type_alias_bounds] static STATIC: u32 = 0; @@ -42,10 +42,11 @@ fn foo<'a>(y: &'a i32) { struct Sendable<T: Send>(T); type MySendable<T> = Sendable<T>; // no error here! -// However, bounds *are* taken into account when accessing associated types +// Bounds on type params do enable shorthand type alias paths. +// However, that doesn't actually mean that they are properly enforced. trait Bound { type Assoc; } -type T1<U: Bound> = U::Assoc; //~ WARN not enforced in type aliases -type T2<U> where U: Bound = U::Assoc; //~ WARN not enforced in type aliases +type T1<U: Bound> = U::Assoc; //~ WARN are not enforced +type T2<U> where U: Bound = U::Assoc; //~ WARN are not enforced // This errors: // `type T3<U> = U::Assoc;` @@ -53,7 +54,7 @@ type T2<U> where U: Bound = U::Assoc; //~ WARN not enforced in type aliases type T4<U> = <U as Bound>::Assoc; // Make sure the help about associated types is not shown incorrectly -type T5<U: Bound> = <U as Bound>::Assoc; //~ WARN not enforced in type aliases -type T6<U: Bound> = ::std::vec::Vec<U>; //~ WARN not enforced in type aliases +type T5<U: Bound> = <U as Bound>::Assoc; //~ WARN are not enforced +type T6<U: Bound> = ::std::vec::Vec<U>; //~ WARN are not enforced fn main() {} diff --git a/tests/ui/type/type-alias-bounds.stderr b/tests/ui/type/type-alias-bounds.stderr index 92e573393c9..15c00901066 100644 --- a/tests/ui/type/type-alias-bounds.stderr +++ b/tests/ui/type/type-alias-bounds.stderr @@ -1,121 +1,132 @@ -warning: bounds on generic parameters are not enforced in type aliases +warning: bounds on generic parameters in type aliases are not enforced --> $DIR/type-alias-bounds.rs:8:14 | LL | type SVec<T: Send + Send> = Vec<T>; - | ^^^^ ^^^^ - | + | --^^^^---^^^^ + | | | + | | will not be checked at usage sites of the type alias + | help: remove this bound + | + = note: this is a known limitation of the type checker that may be lifted in a future edition. + see issue #112792 <https://github.com/rust-lang/rust/issues/112792> for more information + = help: add `#![feature(lazy_type_alias)]` to the crate attributes to enable the desired semantics = note: `#[warn(type_alias_bounds)]` on by default -help: the bound will not be checked when the type alias is used, and should be removed - | -LL - type SVec<T: Send + Send> = Vec<T>; -LL + type SVec<T> = Vec<T>; - | -warning: where clauses are not enforced in type aliases +warning: where clauses on type aliases are not enforced --> $DIR/type-alias-bounds.rs:10:21 | LL | type S2Vec<T> where T: Send = Vec<T>; - | ^^^^^^^ - | -help: the clause will not be checked when the type alias is used, and should be removed - | -LL - type S2Vec<T> where T: Send = Vec<T>; -LL + type S2Vec<T> = Vec<T>; - | + | ------^^^^^^^ + | | | + | | will not be checked at usage sites of the type alias + | help: remove this where clause + | + = note: this is a known limitation of the type checker that may be lifted in a future edition. + see issue #112792 <https://github.com/rust-lang/rust/issues/112792> for more information + = help: add `#![feature(lazy_type_alias)]` to the crate attributes to enable the desired semantics -warning: bounds on generic parameters are not enforced in type aliases +warning: bounds on generic parameters in type aliases are not enforced --> $DIR/type-alias-bounds.rs:12:19 | LL | type VVec<'b, 'a: 'b + 'b> = (&'b u32, Vec<&'a i32>); - | ^^ ^^ - | -help: the bound will not be checked when the type alias is used, and should be removed - | -LL - type VVec<'b, 'a: 'b + 'b> = (&'b u32, Vec<&'a i32>); -LL + type VVec<'b, 'a> = (&'b u32, Vec<&'a i32>); - | + | --^^---^^ + | | | + | | will not be checked at usage sites of the type alias + | help: remove this bound + | + = note: this is a known limitation of the type checker that may be lifted in a future edition. + see issue #112792 <https://github.com/rust-lang/rust/issues/112792> for more information + = help: add `#![feature(lazy_type_alias)]` to the crate attributes to enable the desired semantics -warning: bounds on generic parameters are not enforced in type aliases +warning: bounds on generic parameters in type aliases are not enforced --> $DIR/type-alias-bounds.rs:14:18 | LL | type WVec<'b, T: 'b + 'b> = (&'b u32, Vec<T>); - | ^^ ^^ - | -help: the bound will not be checked when the type alias is used, and should be removed - | -LL - type WVec<'b, T: 'b + 'b> = (&'b u32, Vec<T>); -LL + type WVec<'b, T> = (&'b u32, Vec<T>); - | + | --^^---^^ + | | | + | | will not be checked at usage sites of the type alias + | help: remove this bound + | + = note: this is a known limitation of the type checker that may be lifted in a future edition. + see issue #112792 <https://github.com/rust-lang/rust/issues/112792> for more information + = help: add `#![feature(lazy_type_alias)]` to the crate attributes to enable the desired semantics -warning: where clauses are not enforced in type aliases +warning: where clauses on type aliases are not enforced --> $DIR/type-alias-bounds.rs:16:25 | LL | type W2Vec<'b, T> where T: 'b, T: 'b = (&'b u32, Vec<T>); - | ^^^^^ ^^^^^ - | -help: the clause will not be checked when the type alias is used, and should be removed - | -LL - type W2Vec<'b, T> where T: 'b, T: 'b = (&'b u32, Vec<T>); -LL + type W2Vec<'b, T> = (&'b u32, Vec<T>); - | + | ------^^^^^--^^^^^ + | | | + | | will not be checked at usage sites of the type alias + | help: remove this where clause + | + = note: this is a known limitation of the type checker that may be lifted in a future edition. + see issue #112792 <https://github.com/rust-lang/rust/issues/112792> for more information + = help: add `#![feature(lazy_type_alias)]` to the crate attributes to enable the desired semantics -warning: bounds on generic parameters are not enforced in type aliases - --> $DIR/type-alias-bounds.rs:47:12 +warning: bounds on generic parameters in type aliases are not enforced + --> $DIR/type-alias-bounds.rs:48:12 | LL | type T1<U: Bound> = U::Assoc; - | ^^^^^ + | ^^^^^ will not be checked at usage sites of the type alias | -help: use fully disambiguated paths (i.e., `<T as Trait>::Assoc`) to refer to associated types in type aliases - --> $DIR/type-alias-bounds.rs:47:21 - | -LL | type T1<U: Bound> = U::Assoc; - | ^^^^^^^^ -help: the bound will not be checked when the type alias is used, and should be removed + = note: this is a known limitation of the type checker that may be lifted in a future edition. + see issue #112792 <https://github.com/rust-lang/rust/issues/112792> for more information + = help: add `#![feature(lazy_type_alias)]` to the crate attributes to enable the desired semantics +help: remove this bound | LL - type T1<U: Bound> = U::Assoc; LL + type T1<U> = U::Assoc; | +help: fully qualify this associated type + | +LL | type T1<U: Bound> = <U as /* Trait */>::Assoc; + | + +++++++++++++++ -warning: where clauses are not enforced in type aliases - --> $DIR/type-alias-bounds.rs:48:18 +warning: where clauses on type aliases are not enforced + --> $DIR/type-alias-bounds.rs:49:18 | LL | type T2<U> where U: Bound = U::Assoc; - | ^^^^^^^^ + | ^^^^^^^^ will not be checked at usage sites of the type alias | -help: use fully disambiguated paths (i.e., `<T as Trait>::Assoc`) to refer to associated types in type aliases - --> $DIR/type-alias-bounds.rs:48:29 - | -LL | type T2<U> where U: Bound = U::Assoc; - | ^^^^^^^^ -help: the clause will not be checked when the type alias is used, and should be removed + = note: this is a known limitation of the type checker that may be lifted in a future edition. + see issue #112792 <https://github.com/rust-lang/rust/issues/112792> for more information + = help: add `#![feature(lazy_type_alias)]` to the crate attributes to enable the desired semantics +help: remove this where clause | LL - type T2<U> where U: Bound = U::Assoc; LL + type T2<U> = U::Assoc; | +help: fully qualify this associated type + | +LL | type T2<U> where U: Bound = <U as /* Trait */>::Assoc; + | + +++++++++++++++ -warning: bounds on generic parameters are not enforced in type aliases - --> $DIR/type-alias-bounds.rs:56:12 +warning: bounds on generic parameters in type aliases are not enforced + --> $DIR/type-alias-bounds.rs:57:12 | LL | type T5<U: Bound> = <U as Bound>::Assoc; - | ^^^^^ - | -help: the bound will not be checked when the type alias is used, and should be removed - | -LL - type T5<U: Bound> = <U as Bound>::Assoc; -LL + type T5<U> = <U as Bound>::Assoc; - | + | --^^^^^ + | | | + | | will not be checked at usage sites of the type alias + | help: remove this bound + | + = note: this is a known limitation of the type checker that may be lifted in a future edition. + see issue #112792 <https://github.com/rust-lang/rust/issues/112792> for more information + = help: add `#![feature(lazy_type_alias)]` to the crate attributes to enable the desired semantics -warning: bounds on generic parameters are not enforced in type aliases - --> $DIR/type-alias-bounds.rs:57:12 +warning: bounds on generic parameters in type aliases are not enforced + --> $DIR/type-alias-bounds.rs:58:12 | LL | type T6<U: Bound> = ::std::vec::Vec<U>; - | ^^^^^ - | -help: the bound will not be checked when the type alias is used, and should be removed - | -LL - type T6<U: Bound> = ::std::vec::Vec<U>; -LL + type T6<U> = ::std::vec::Vec<U>; - | + | --^^^^^ + | | | + | | will not be checked at usage sites of the type alias + | help: remove this bound + | + = note: this is a known limitation of the type checker that may be lifted in a future edition. + see issue #112792 <https://github.com/rust-lang/rust/issues/112792> for more information + = help: add `#![feature(lazy_type_alias)]` to the crate attributes to enable the desired semantics warning: 9 warnings emitted diff --git a/tests/ui/uninhabited/uninhabited-patterns.stderr b/tests/ui/uninhabited/uninhabited-patterns.stderr index a6fda88f032..ca62386d7ef 100644 --- a/tests/ui/uninhabited/uninhabited-patterns.stderr +++ b/tests/ui/uninhabited/uninhabited-patterns.stderr @@ -4,6 +4,7 @@ error: unreachable pattern LL | Ok(box _) => (), | ^^^^^^^^^ | + = note: this pattern matches no values because `NotSoSecretlyEmpty` is uninhabited note: the lint level is defined here --> $DIR/uninhabited-patterns.rs:4:9 | @@ -15,12 +16,16 @@ error: unreachable pattern | LL | Err(Ok(_y)) => (), | ^^^^^^^^^^^ + | + = note: this pattern matches no values because `NotSoSecretlyEmpty` is uninhabited error: unreachable pattern --> $DIR/uninhabited-patterns.rs:42:15 | LL | while let Some(_y) = foo() { | ^^^^^^^^ + | + = note: this pattern matches no values because `NotSoSecretlyEmpty` is uninhabited error: aborting due to 3 previous errors diff --git a/tests/ui/unsized/maybe-bounds-where.stderr b/tests/ui/unsized/maybe-bounds-where.stderr index 683bd387bb2..f7851261667 100644 --- a/tests/ui/unsized/maybe-bounds-where.stderr +++ b/tests/ui/unsized/maybe-bounds-where.stderr @@ -1,32 +1,47 @@ -error: `?Trait` bounds are only permitted at the point where a type parameter is declared +error[E0658]: `?Trait` bounds are only permitted at the point where a type parameter is declared --> $DIR/maybe-bounds-where.rs:1:28 | LL | struct S1<T>(T) where (T): ?Sized; | ^^^^^^ + | + = help: add `#![feature(more_maybe_bounds)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date -error: `?Trait` bounds are only permitted at the point where a type parameter is declared +error[E0658]: `?Trait` bounds are only permitted at the point where a type parameter is declared --> $DIR/maybe-bounds-where.rs:4:27 | LL | struct S2<T>(T) where u8: ?Sized; | ^^^^^^ + | + = help: add `#![feature(more_maybe_bounds)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date -error: `?Trait` bounds are only permitted at the point where a type parameter is declared +error[E0658]: `?Trait` bounds are only permitted at the point where a type parameter is declared --> $DIR/maybe-bounds-where.rs:7:35 | LL | struct S3<T>(T) where &'static T: ?Sized; | ^^^^^^ + | + = help: add `#![feature(more_maybe_bounds)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date -error: `?Trait` bounds are only permitted at the point where a type parameter is declared +error[E0658]: `?Trait` bounds are only permitted at the point where a type parameter is declared --> $DIR/maybe-bounds-where.rs:12:34 | LL | struct S4<T>(T) where for<'a> T: ?Trait<'a>; | ^^^^^^^^^^ + | + = help: add `#![feature(more_maybe_bounds)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date -error: `?Trait` bounds are only permitted at the point where a type parameter is declared +error[E0658]: `?Trait` bounds are only permitted at the point where a type parameter is declared --> $DIR/maybe-bounds-where.rs:21:21 | LL | fn f() where T: ?Sized {} | ^^^^^^ + | + = help: add `#![feature(more_maybe_bounds)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date warning: relaxing a default bound only does something for `?Sized`; all other traits are not bound by default --> $DIR/maybe-bounds-where.rs:12:34 @@ -39,6 +54,9 @@ error[E0203]: type parameter has more than one relaxed default bound, only one i | LL | struct S5<T>(*const T) where T: ?Trait<'static> + ?Sized; | ^^^^^^^^^^^^^^^ ^^^^^^ + | + = help: add `#![feature(more_maybe_bounds)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date warning: relaxing a default bound only does something for `?Sized`; all other traits are not bound by default --> $DIR/maybe-bounds-where.rs:16:33 @@ -48,4 +66,5 @@ LL | struct S5<T>(*const T) where T: ?Trait<'static> + ?Sized; error: aborting due to 6 previous errors; 2 warnings emitted -For more information about this error, try `rustc --explain E0203`. +Some errors have detailed explanations: E0203, E0658. +For more information about an error, try `rustc --explain E0203`. diff --git a/tests/ui/variance/variance-issue-20533.stderr b/tests/ui/variance/variance-issue-20533.stderr index 03cada07a9e..0a810b7222e 100644 --- a/tests/ui/variance/variance-issue-20533.stderr +++ b/tests/ui/variance/variance-issue-20533.stderr @@ -73,10 +73,14 @@ LL | drop(a); LL | drop(x); | - borrow later used here | -help: consider cloning the value if the performance cost is acceptable +note: if `AffineU32` implemented `Clone`, you could clone the value + --> $DIR/variance-issue-20533.rs:26:1 | -LL | let x = bat(&a).clone(); - | ++++++++ +LL | struct AffineU32(u32); + | ^^^^^^^^^^^^^^^^ consider implementing `Clone` for this type +... +LL | let x = bat(&a); + | -- you could clone this value error[E0505]: cannot move out of `a` because it is borrowed --> $DIR/variance-issue-20533.rs:59:14 |
