diff options
Diffstat (limited to 'tests')
66 files changed, 1592 insertions, 157 deletions
diff --git a/tests/codegen/issues/issue-86106.rs b/tests/codegen/issues/issue-86106.rs index 15aef344ac0..5f71d46fb20 100644 --- a/tests/codegen/issues/issue-86106.rs +++ b/tests/codegen/issues/issue-86106.rs @@ -9,9 +9,12 @@ // CHECK-LABEL: define {{(dso_local )?}}void @string_new #[no_mangle] pub fn string_new() -> String { - // CHECK: store ptr inttoptr + // CHECK-NOT: load i8 + // CHECK: store i{{32|64}} // CHECK-NEXT: getelementptr - // CHECK-NEXT: call void @llvm.memset + // CHECK-NEXT: store ptr + // CHECK-NEXT: getelementptr + // CHECK-NEXT: store i{{32|64}} // CHECK-NEXT: ret void String::new() } @@ -19,9 +22,12 @@ pub fn string_new() -> String { // CHECK-LABEL: define {{(dso_local )?}}void @empty_to_string #[no_mangle] pub fn empty_to_string() -> String { - // CHECK: store ptr inttoptr + // CHECK-NOT: load i8 + // CHECK: store i{{32|64}} + // CHECK-NEXT: getelementptr + // CHECK-NEXT: store ptr // CHECK-NEXT: getelementptr - // CHECK-NEXT: call void @llvm.memset + // CHECK-NEXT: store i{{32|64}} // CHECK-NEXT: ret void "".to_string() } @@ -32,9 +38,12 @@ pub fn empty_to_string() -> String { // CHECK-LABEL: @empty_vec #[no_mangle] pub fn empty_vec() -> Vec<u8> { - // CHECK: store ptr inttoptr + // CHECK: store i{{32|64}} + // CHECK-NOT: load i8 // CHECK-NEXT: getelementptr - // CHECK-NEXT: call void @llvm.memset + // CHECK-NEXT: store ptr + // CHECK-NEXT: getelementptr + // CHECK-NEXT: store i{{32|64}} // CHECK-NEXT: ret void vec![] } @@ -42,9 +51,12 @@ pub fn empty_vec() -> Vec<u8> { // CHECK-LABEL: @empty_vec_clone #[no_mangle] pub fn empty_vec_clone() -> Vec<u8> { - // CHECK: store ptr inttoptr + // CHECK: store i{{32|64}} + // CHECK-NOT: load i8 + // CHECK-NEXT: getelementptr + // CHECK-NEXT: store ptr // CHECK-NEXT: getelementptr - // CHECK-NEXT: call void @llvm.memset + // CHECK-NEXT: store i{{32|64}} // CHECK-NEXT: ret void vec![].clone() } diff --git a/tests/coverage/async_block.cov-map b/tests/coverage/async_block.cov-map new file mode 100644 index 00000000000..104133f6e67 --- /dev/null +++ b/tests/coverage/async_block.cov-map @@ -0,0 +1,32 @@ +Function name: async_block::main +Raw bytes (38): 0x[01, 01, 02, 01, 05, 03, 05, 06, 01, 05, 01, 00, 0b, 05, 01, 09, 00, 0a, 03, 00, 0e, 00, 13, 05, 00, 14, 01, 16, 05, 07, 0a, 02, 06, 06, 03, 01, 00, 02] +Number of files: 1 +- file 0 => global file 1 +Number of expressions: 2 +- expression 0 operands: lhs = Counter(0), rhs = Counter(1) +- expression 1 operands: lhs = Expression(0, Add), rhs = Counter(1) +Number of file 0 mappings: 6 +- Code(Counter(0)) at (prev + 5, 1) to (start + 0, 11) +- Code(Counter(1)) at (prev + 1, 9) to (start + 0, 10) +- Code(Expression(0, Add)) at (prev + 0, 14) to (start + 0, 19) + = (c0 + c1) +- Code(Counter(1)) at (prev + 0, 20) to (start + 1, 22) +- Code(Counter(1)) at (prev + 7, 10) to (start + 2, 6) +- Code(Expression(1, Sub)) at (prev + 3, 1) to (start + 0, 2) + = ((c0 + c1) - c1) + +Function name: async_block::main::{closure#0} +Raw bytes (28): 0x[01, 01, 02, 01, 05, 05, 02, 04, 01, 07, 1c, 01, 17, 05, 01, 18, 02, 0e, 02, 02, 14, 02, 0e, 07, 03, 09, 00, 0a] +Number of files: 1 +- file 0 => global file 1 +Number of expressions: 2 +- expression 0 operands: lhs = Counter(0), rhs = Counter(1) +- expression 1 operands: lhs = Counter(1), rhs = Expression(0, Sub) +Number of file 0 mappings: 4 +- Code(Counter(0)) at (prev + 7, 28) to (start + 1, 23) +- Code(Counter(1)) at (prev + 1, 24) to (start + 2, 14) +- Code(Expression(0, Sub)) at (prev + 2, 20) to (start + 2, 14) + = (c0 - c1) +- Code(Expression(1, Add)) at (prev + 3, 9) to (start + 0, 10) + = (c1 + (c0 - c1)) + diff --git a/tests/coverage/async_block.coverage b/tests/coverage/async_block.coverage new file mode 100644 index 00000000000..297397ca26c --- /dev/null +++ b/tests/coverage/async_block.coverage @@ -0,0 +1,37 @@ + LL| |#![feature(coverage_attribute)] + LL| |#![feature(noop_waker)] + LL| |// edition: 2021 + LL| | + LL| 1|fn main() { + LL| 17| for i in 0..16 { + ^16 + LL| 16| let future = async { + LL| 16| if i >= 12 { + LL| 4| println!("big"); + LL| 12| } else { + LL| 12| println!("small"); + LL| 12| } + LL| 16| }; + LL| 16| executor::block_on(future); + LL| 16| } + LL| 1|} + LL| | + LL| |mod executor { + LL| | use core::future::Future; + LL| | use core::pin::pin; + LL| | use core::task::{Context, Poll, Waker}; + LL| | + LL| | #[coverage(off)] + LL| | pub fn block_on<F: Future>(mut future: F) -> F::Output { + LL| | let mut future = pin!(future); + LL| | let waker = Waker::noop(); + LL| | let mut context = Context::from_waker(&waker); + LL| | + LL| | loop { + LL| | if let Poll::Ready(val) = future.as_mut().poll(&mut context) { + LL| | break val; + LL| | } + LL| | } + LL| | } + LL| |} + diff --git a/tests/coverage/async_block.rs b/tests/coverage/async_block.rs new file mode 100644 index 00000000000..9d8647bf1f2 --- /dev/null +++ b/tests/coverage/async_block.rs @@ -0,0 +1,35 @@ +#![feature(coverage_attribute)] +#![feature(noop_waker)] +// edition: 2021 + +fn main() { + for i in 0..16 { + let future = async { + if i >= 12 { + println!("big"); + } else { + println!("small"); + } + }; + executor::block_on(future); + } +} + +mod executor { + use core::future::Future; + use core::pin::pin; + use core::task::{Context, Poll, Waker}; + + #[coverage(off)] + pub fn block_on<F: Future>(mut future: F) -> F::Output { + let mut future = pin!(future); + let waker = Waker::noop(); + let mut context = Context::from_waker(&waker); + + loop { + if let Poll::Ready(val) = future.as_mut().poll(&mut context) { + break val; + } + } + } +} diff --git a/tests/coverage/no_spans_if_not.cov-map b/tests/coverage/no_spans_if_not.cov-map new file mode 100644 index 00000000000..5277267ec1b --- /dev/null +++ b/tests/coverage/no_spans_if_not.cov-map @@ -0,0 +1,8 @@ +Function name: no_spans_if_not::main +Raw bytes (9): 0x[01, 01, 00, 01, 01, 0b, 01, 02, 02] +Number of files: 1 +- file 0 => global file 1 +Number of expressions: 0 +Number of file 0 mappings: 1 +- Code(Counter(0)) at (prev + 11, 1) to (start + 2, 2) + diff --git a/tests/coverage/no_spans_if_not.coverage b/tests/coverage/no_spans_if_not.coverage new file mode 100644 index 00000000000..1b6bbc75a04 --- /dev/null +++ b/tests/coverage/no_spans_if_not.coverage @@ -0,0 +1,30 @@ + LL| |// edition: 2021 + LL| | + LL| |// If the span extractor can't find any relevant spans for a function, + LL| |// but the function contains coverage span-marker statements (e.g. inserted + LL| |// for `if !`), coverage codegen may think that it is instrumented and + LL| |// consequently complain that it has no spans. + LL| |// + LL| |// Regression test for <https://github.com/rust-lang/rust/issues/118850>, + LL| |// "A used function should have had coverage mapping data but did not". + LL| | + LL| 1|fn main() { + LL| 1| affected_function(); + LL| 1|} + LL| | + LL| |macro_rules! macro_that_defines_a_function { + LL| | (fn $name:ident () $body:tt) => { + LL| | fn $name () $body + LL| | } + LL| |} + LL| | + LL| |macro_that_defines_a_function! { + LL| | fn affected_function() { + LL| | if !false { + LL| | () + LL| | } else { + LL| | () + LL| | } + LL| | } + LL| |} + diff --git a/tests/coverage/no_spans_if_not.rs b/tests/coverage/no_spans_if_not.rs new file mode 100644 index 00000000000..2bbdc11cd5e --- /dev/null +++ b/tests/coverage/no_spans_if_not.rs @@ -0,0 +1,29 @@ +// edition: 2021 + +// If the span extractor can't find any relevant spans for a function, +// but the function contains coverage span-marker statements (e.g. inserted +// for `if !`), coverage codegen may think that it is instrumented and +// consequently complain that it has no spans. +// +// Regression test for <https://github.com/rust-lang/rust/issues/118850>, +// "A used function should have had coverage mapping data but did not". + +fn main() { + affected_function(); +} + +macro_rules! macro_that_defines_a_function { + (fn $name:ident () $body:tt) => { + fn $name () $body + } +} + +macro_that_defines_a_function! { + fn affected_function() { + if !false { + () + } else { + () + } + } +} diff --git a/tests/incremental/thinlto/cgu_invalidated_via_import.rs b/tests/incremental/thinlto/cgu_invalidated_via_import.rs index e0cd385eff3..a81b4f7e9d0 100644 --- a/tests/incremental/thinlto/cgu_invalidated_via_import.rs +++ b/tests/incremental/thinlto/cgu_invalidated_via_import.rs @@ -14,14 +14,14 @@ kind="no")] #![rustc_expected_cgu_reuse(module="cgu_invalidated_via_import-foo", cfg="cfail3", - kind="post-lto")] + kind="pre-lto")] // Should be "post-lto", see issue #119076 #![rustc_expected_cgu_reuse(module="cgu_invalidated_via_import-bar", cfg="cfail2", kind="pre-lto")] #![rustc_expected_cgu_reuse(module="cgu_invalidated_via_import-bar", cfg="cfail3", - kind="post-lto")] + kind="pre-lto")] // Should be "post-lto", see issue #119076 mod foo { diff --git a/tests/incremental/thinlto/cgu_keeps_identical_fn.rs b/tests/incremental/thinlto/cgu_keeps_identical_fn.rs index 781aae578d4..9e840f67ab2 100644 --- a/tests/incremental/thinlto/cgu_keeps_identical_fn.rs +++ b/tests/incremental/thinlto/cgu_keeps_identical_fn.rs @@ -9,21 +9,25 @@ #![feature(rustc_attrs)] #![crate_type = "rlib"] -#![rustc_expected_cgu_reuse(module = "cgu_keeps_identical_fn-foo", cfg = "cfail2", kind = "no")] +#![rustc_expected_cgu_reuse( + module = "cgu_keeps_identical_fn-foo", + cfg = "cfail2", + kind = "pre-lto" +)] #![rustc_expected_cgu_reuse( module = "cgu_keeps_identical_fn-foo", cfg = "cfail3", - kind = "post-lto" + kind = "pre-lto" // Should be "post-lto", see issue #119076 )] #![rustc_expected_cgu_reuse( module = "cgu_keeps_identical_fn-bar", cfg = "cfail2", - kind = "post-lto" + kind = "pre-lto" // Should be "post-lto", see issue #119076 )] #![rustc_expected_cgu_reuse( module = "cgu_keeps_identical_fn-bar", cfg = "cfail3", - kind = "post-lto" + kind = "pre-lto" // Should be "post-lto", see issue #119076 )] mod foo { diff --git a/tests/incremental/thinlto/independent_cgus_dont_affect_each_other.rs b/tests/incremental/thinlto/independent_cgus_dont_affect_each_other.rs index 8aa036ec978..45eb1382874 100644 --- a/tests/incremental/thinlto/independent_cgus_dont_affect_each_other.rs +++ b/tests/incremental/thinlto/independent_cgus_dont_affect_each_other.rs @@ -13,21 +13,21 @@ kind="no")] #![rustc_expected_cgu_reuse(module="independent_cgus_dont_affect_each_other-foo", cfg="cfail3", - kind="post-lto")] + kind="pre-lto")] // Should be "post-lto", see issue #119076 #![rustc_expected_cgu_reuse(module="independent_cgus_dont_affect_each_other-bar", cfg="cfail2", kind="pre-lto")] #![rustc_expected_cgu_reuse(module="independent_cgus_dont_affect_each_other-bar", cfg="cfail3", - kind="post-lto")] + kind="pre-lto")] // Should be "post-lto", see issue #119076 #![rustc_expected_cgu_reuse(module="independent_cgus_dont_affect_each_other-baz", cfg="cfail2", - kind="post-lto")] + kind="pre-lto")] // Should be "post-lto", see issue #119076 #![rustc_expected_cgu_reuse(module="independent_cgus_dont_affect_each_other-baz", cfg="cfail3", - kind="post-lto")] + kind="pre-lto")] // Should be "post-lto", see issue #119076 mod foo { #[cfg(cfail1)] diff --git a/tests/mir-opt/exponential_or.match_tuple.SimplifyCfg-initial.after.mir b/tests/mir-opt/exponential_or.match_tuple.SimplifyCfg-initial.after.mir index b04e09e88b8..596dcef85fd 100644 --- a/tests/mir-opt/exponential_or.match_tuple.SimplifyCfg-initial.after.mir +++ b/tests/mir-opt/exponential_or.match_tuple.SimplifyCfg-initial.after.mir @@ -38,22 +38,22 @@ fn match_tuple(_1: (u32, bool, Option<i32>, u32)) -> u32 { bb4: { _5 = Le(const 6_u32, (_1.3: u32)); - switchInt(move _5) -> [0: bb6, otherwise: bb5]; + switchInt(move _5) -> [0: bb5, otherwise: bb7]; } bb5: { - _6 = Le((_1.3: u32), const 9_u32); - switchInt(move _6) -> [0: bb6, otherwise: bb8]; + _3 = Le(const 13_u32, (_1.3: u32)); + switchInt(move _3) -> [0: bb1, otherwise: bb6]; } bb6: { - _3 = Le(const 13_u32, (_1.3: u32)); - switchInt(move _3) -> [0: bb1, otherwise: bb7]; + _4 = Le((_1.3: u32), const 16_u32); + switchInt(move _4) -> [0: bb1, otherwise: bb8]; } bb7: { - _4 = Le((_1.3: u32), const 16_u32); - switchInt(move _4) -> [0: bb1, otherwise: bb8]; + _6 = Le((_1.3: u32), const 9_u32); + switchInt(move _6) -> [0: bb5, otherwise: bb8]; } bb8: { diff --git a/tests/mir-opt/gvn.constant_index_overflow.GVN.panic-abort.diff b/tests/mir-opt/gvn.constant_index_overflow.GVN.panic-abort.diff new file mode 100644 index 00000000000..4b1e3379114 --- /dev/null +++ b/tests/mir-opt/gvn.constant_index_overflow.GVN.panic-abort.diff @@ -0,0 +1,104 @@ +- // MIR for `constant_index_overflow` before GVN ++ // MIR for `constant_index_overflow` after GVN + + fn constant_index_overflow(_1: &[T]) -> () { + debug x => _1; + let mut _0: (); + let _2: usize; + let mut _4: bool; + let mut _5: usize; + let mut _6: usize; + let mut _7: &[T]; + let _8: usize; + let mut _9: usize; + let mut _10: bool; + let _11: usize; + let mut _12: usize; + let mut _13: bool; + let mut _14: T; + scope 1 { + debug a => _2; + let _3: T; + scope 2 { + debug b => _3; + } + } + + bb0: { +- StorageLive(_2); +- _2 = const _ as usize (IntToInt); ++ nop; ++ _2 = const usize::MAX; + StorageLive(_3); + StorageLive(_4); + StorageLive(_5); +- _5 = _2; ++ _5 = const usize::MAX; + StorageLive(_6); + StorageLive(_7); + _7 = &(*_1); + _6 = core::slice::<impl [T]>::len(move _7) -> [return: bb1, unwind unreachable]; + } + + bb1: { + StorageDead(_7); +- _4 = Lt(move _5, move _6); ++ _4 = Lt(const usize::MAX, move _6); + switchInt(move _4) -> [0: bb4, otherwise: bb2]; + } + + bb2: { + StorageDead(_6); + StorageDead(_5); + StorageLive(_8); +- _8 = _2; ++ _8 = const usize::MAX; + _9 = Len((*_1)); +- _10 = Lt(_8, _9); +- assert(move _10, "index out of bounds: the length is {} but the index is {}", move _9, _8) -> [success: bb3, unwind unreachable]; ++ _10 = Lt(const usize::MAX, _9); ++ assert(move _10, "index out of bounds: the length is {} but the index is {}", move _9, const usize::MAX) -> [success: bb3, unwind unreachable]; + } + + bb3: { +- _3 = (*_1)[_8]; ++ _3 = (*_1)[_2]; + StorageDead(_8); + goto -> bb6; + } + + bb4: { + StorageDead(_6); + StorageDead(_5); + StorageLive(_11); + _11 = const 0_usize; + _12 = Len((*_1)); +- _13 = Lt(_11, _12); +- assert(move _13, "index out of bounds: the length is {} but the index is {}", move _12, _11) -> [success: bb5, unwind unreachable]; ++ _13 = Lt(const 0_usize, _12); ++ assert(move _13, "index out of bounds: the length is {} but the index is {}", move _12, const 0_usize) -> [success: bb5, unwind unreachable]; + } + + bb5: { +- _3 = (*_1)[_11]; ++ _3 = (*_1)[0 of 1]; + StorageDead(_11); + goto -> bb6; + } + + bb6: { + StorageDead(_4); + StorageLive(_14); + _14 = _3; + _0 = opaque::<T>(move _14) -> [return: bb7, unwind unreachable]; + } + + bb7: { + StorageDead(_14); + StorageDead(_3); +- StorageDead(_2); ++ nop; + return; + } + } + diff --git a/tests/mir-opt/gvn.constant_index_overflow.GVN.panic-unwind.diff b/tests/mir-opt/gvn.constant_index_overflow.GVN.panic-unwind.diff new file mode 100644 index 00000000000..8abcd7e9387 --- /dev/null +++ b/tests/mir-opt/gvn.constant_index_overflow.GVN.panic-unwind.diff @@ -0,0 +1,104 @@ +- // MIR for `constant_index_overflow` before GVN ++ // MIR for `constant_index_overflow` after GVN + + fn constant_index_overflow(_1: &[T]) -> () { + debug x => _1; + let mut _0: (); + let _2: usize; + let mut _4: bool; + let mut _5: usize; + let mut _6: usize; + let mut _7: &[T]; + let _8: usize; + let mut _9: usize; + let mut _10: bool; + let _11: usize; + let mut _12: usize; + let mut _13: bool; + let mut _14: T; + scope 1 { + debug a => _2; + let _3: T; + scope 2 { + debug b => _3; + } + } + + bb0: { +- StorageLive(_2); +- _2 = const _ as usize (IntToInt); ++ nop; ++ _2 = const usize::MAX; + StorageLive(_3); + StorageLive(_4); + StorageLive(_5); +- _5 = _2; ++ _5 = const usize::MAX; + StorageLive(_6); + StorageLive(_7); + _7 = &(*_1); + _6 = core::slice::<impl [T]>::len(move _7) -> [return: bb1, unwind continue]; + } + + bb1: { + StorageDead(_7); +- _4 = Lt(move _5, move _6); ++ _4 = Lt(const usize::MAX, move _6); + switchInt(move _4) -> [0: bb4, otherwise: bb2]; + } + + bb2: { + StorageDead(_6); + StorageDead(_5); + StorageLive(_8); +- _8 = _2; ++ _8 = const usize::MAX; + _9 = Len((*_1)); +- _10 = Lt(_8, _9); +- assert(move _10, "index out of bounds: the length is {} but the index is {}", move _9, _8) -> [success: bb3, unwind continue]; ++ _10 = Lt(const usize::MAX, _9); ++ assert(move _10, "index out of bounds: the length is {} but the index is {}", move _9, const usize::MAX) -> [success: bb3, unwind continue]; + } + + bb3: { +- _3 = (*_1)[_8]; ++ _3 = (*_1)[_2]; + StorageDead(_8); + goto -> bb6; + } + + bb4: { + StorageDead(_6); + StorageDead(_5); + StorageLive(_11); + _11 = const 0_usize; + _12 = Len((*_1)); +- _13 = Lt(_11, _12); +- assert(move _13, "index out of bounds: the length is {} but the index is {}", move _12, _11) -> [success: bb5, unwind continue]; ++ _13 = Lt(const 0_usize, _12); ++ assert(move _13, "index out of bounds: the length is {} but the index is {}", move _12, const 0_usize) -> [success: bb5, unwind continue]; + } + + bb5: { +- _3 = (*_1)[_11]; ++ _3 = (*_1)[0 of 1]; + StorageDead(_11); + goto -> bb6; + } + + bb6: { + StorageDead(_4); + StorageLive(_14); + _14 = _3; + _0 = opaque::<T>(move _14) -> [return: bb7, unwind continue]; + } + + bb7: { + StorageDead(_14); + StorageDead(_3); +- StorageDead(_2); ++ nop; + return; + } + } + diff --git a/tests/mir-opt/gvn.rs b/tests/mir-opt/gvn.rs index 6e082acdbd3..db131f7f97d 100644 --- a/tests/mir-opt/gvn.rs +++ b/tests/mir-opt/gvn.rs @@ -609,6 +609,22 @@ fn indirect_static() { }) } +/// Verify that having constant index `u64::MAX` does not yield to an overflow in rustc. +fn constant_index_overflow<T: Copy>(x: &[T]) { + // CHECK-LABEL: fn constant_index_overflow( + // CHECK: debug a => [[a:_.*]]; + // CHECK: debug b => [[b:_.*]]; + // CHECK: [[a]] = const usize::MAX; + // CHECK-NOT: = (*_1)[{{.*}} of 0]; + // CHECK: [[b]] = (*_1)[[[a]]]; + // CHECK-NOT: = (*_1)[{{.*}} of 0]; + // CHECK: [[b]] = (*_1)[0 of 1]; + // CHECK-NOT: = (*_1)[{{.*}} of 0]; + let a = u64::MAX as usize; + let b = if a < x.len() { x[a] } else { x[0] }; + opaque(b) +} + fn main() { subexpression_elimination(2, 4, 5); wrap_unwrap(5); @@ -627,6 +643,7 @@ fn main() { repeat(); fn_pointers(); indirect_static(); + constant_index_overflow(&[5, 3]); } #[inline(never)] @@ -653,3 +670,4 @@ fn identity<T>(x: T) -> T { // EMIT_MIR gvn.repeat.GVN.diff // EMIT_MIR gvn.fn_pointers.GVN.diff // EMIT_MIR gvn.indirect_static.GVN.diff +// EMIT_MIR gvn.constant_index_overflow.GVN.diff diff --git a/tests/mir-opt/match_test.main.SimplifyCfg-initial.after.mir b/tests/mir-opt/match_test.main.SimplifyCfg-initial.after.mir index ebb2f70a475..5bf78b6150f 100644 --- a/tests/mir-opt/match_test.main.SimplifyCfg-initial.after.mir +++ b/tests/mir-opt/match_test.main.SimplifyCfg-initial.after.mir @@ -28,43 +28,43 @@ fn main() -> () { StorageLive(_3); PlaceMention(_1); _6 = Le(const 0_i32, _1); - switchInt(move _6) -> [0: bb4, otherwise: bb1]; + switchInt(move _6) -> [0: bb3, otherwise: bb8]; } bb1: { - _7 = Lt(_1, const 10_i32); - switchInt(move _7) -> [0: bb4, otherwise: bb2]; + falseEdge -> [real: bb9, imaginary: bb4]; } bb2: { - falseEdge -> [real: bb9, imaginary: bb6]; + _3 = const 3_i32; + goto -> bb14; } bb3: { - _3 = const 3_i32; - goto -> bb14; + _4 = Le(const 10_i32, _1); + switchInt(move _4) -> [0: bb5, otherwise: bb7]; } bb4: { - _4 = Le(const 10_i32, _1); - switchInt(move _4) -> [0: bb7, otherwise: bb5]; + falseEdge -> [real: bb12, imaginary: bb6]; } bb5: { - _5 = Le(_1, const 20_i32); - switchInt(move _5) -> [0: bb7, otherwise: bb6]; + switchInt(_1) -> [4294967295: bb6, otherwise: bb2]; } bb6: { - falseEdge -> [real: bb12, imaginary: bb8]; + falseEdge -> [real: bb13, imaginary: bb2]; } bb7: { - switchInt(_1) -> [4294967295: bb8, otherwise: bb3]; + _5 = Le(_1, const 20_i32); + switchInt(move _5) -> [0: bb5, otherwise: bb4]; } bb8: { - falseEdge -> [real: bb13, imaginary: bb3]; + _7 = Lt(_1, const 10_i32); + switchInt(move _7) -> [0: bb3, otherwise: bb1]; } bb9: { @@ -83,7 +83,7 @@ fn main() -> () { bb11: { StorageDead(_9); - falseEdge -> [real: bb3, imaginary: bb6]; + falseEdge -> [real: bb2, imaginary: bb4]; } bb12: { diff --git a/tests/ui-fulldeps/internal-lints/diagnostics.rs b/tests/ui-fulldeps/internal-lints/diagnostics.rs index 7f545ead152..4b006151c64 100644 --- a/tests/ui-fulldeps/internal-lints/diagnostics.rs +++ b/tests/ui-fulldeps/internal-lints/diagnostics.rs @@ -13,7 +13,7 @@ extern crate rustc_session; extern crate rustc_span; use rustc_errors::{ - AddToDiagnostic, Diagnostic, DiagnosticBuilder, DiagnosticMessage, ErrorGuaranteed, Handler, + AddToDiagnostic, DiagCtxt, Diagnostic, DiagnosticBuilder, DiagnosticMessage, ErrorGuaranteed, IntoDiagnostic, SubdiagnosticMessage, }; use rustc_macros::{Diagnostic, Subdiagnostic}; @@ -38,8 +38,8 @@ struct Note { pub struct UntranslatableInIntoDiagnostic; impl<'a> IntoDiagnostic<'a, ErrorGuaranteed> for UntranslatableInIntoDiagnostic { - fn into_diagnostic(self, handler: &'a Handler) -> DiagnosticBuilder<'a, ErrorGuaranteed> { - handler.struct_err("untranslatable diagnostic") + fn into_diagnostic(self, dcx: &'a DiagCtxt) -> DiagnosticBuilder<'a, ErrorGuaranteed> { + dcx.struct_err("untranslatable diagnostic") //~^ ERROR diagnostics should be created using translatable messages } } @@ -47,8 +47,8 @@ impl<'a> IntoDiagnostic<'a, ErrorGuaranteed> for UntranslatableInIntoDiagnostic pub struct TranslatableInIntoDiagnostic; impl<'a> IntoDiagnostic<'a, ErrorGuaranteed> for TranslatableInIntoDiagnostic { - fn into_diagnostic(self, handler: &'a Handler) -> DiagnosticBuilder<'a, ErrorGuaranteed> { - handler.struct_err(crate::fluent_generated::no_crate_example) + fn into_diagnostic(self, dcx: &'a DiagCtxt) -> DiagnosticBuilder<'a, ErrorGuaranteed> { + dcx.struct_err(crate::fluent_generated::no_crate_example) } } @@ -75,11 +75,11 @@ impl AddToDiagnostic for TranslatableInAddToDiagnostic { } } -pub fn make_diagnostics<'a>(handler: &'a Handler) { - let _diag = handler.struct_err(crate::fluent_generated::no_crate_example); +pub fn make_diagnostics<'a>(dcx: &'a DiagCtxt) { + let _diag = dcx.struct_err(crate::fluent_generated::no_crate_example); //~^ ERROR diagnostics should only be created in `IntoDiagnostic`/`AddToDiagnostic` impls - let _diag = handler.struct_err("untranslatable diagnostic"); + let _diag = dcx.struct_err("untranslatable diagnostic"); //~^ ERROR diagnostics should only be created in `IntoDiagnostic`/`AddToDiagnostic` impls //~^^ ERROR diagnostics should be created using translatable messages } @@ -87,6 +87,6 @@ pub fn make_diagnostics<'a>(handler: &'a Handler) { // Check that `rustc_lint_diagnostics`-annotated functions aren't themselves linted. #[rustc_lint_diagnostics] -pub fn skipped_because_of_annotation<'a>(handler: &'a Handler) { - let _diag = handler.struct_err("untranslatable diagnostic"); // okay! +pub fn skipped_because_of_annotation<'a>(dcx: &'a DiagCtxt) { + let _diag = dcx.struct_err("untranslatable diagnostic"); // okay! } diff --git a/tests/ui-fulldeps/internal-lints/diagnostics.stderr b/tests/ui-fulldeps/internal-lints/diagnostics.stderr index 8e0535e021b..d18db3cbbd3 100644 --- a/tests/ui-fulldeps/internal-lints/diagnostics.stderr +++ b/tests/ui-fulldeps/internal-lints/diagnostics.stderr @@ -1,8 +1,8 @@ error: diagnostics should be created using translatable messages - --> $DIR/diagnostics.rs:42:17 + --> $DIR/diagnostics.rs:42:13 | -LL | handler.struct_err("untranslatable diagnostic") - | ^^^^^^^^^^ +LL | dcx.struct_err("untranslatable diagnostic") + | ^^^^^^^^^^ | note: the lint level is defined here --> $DIR/diagnostics.rs:6:9 @@ -17,10 +17,10 @@ LL | diag.note("untranslatable diagnostic"); | ^^^^ error: diagnostics should only be created in `IntoDiagnostic`/`AddToDiagnostic` impls - --> $DIR/diagnostics.rs:79:25 + --> $DIR/diagnostics.rs:79:21 | -LL | let _diag = handler.struct_err(crate::fluent_generated::no_crate_example); - | ^^^^^^^^^^ +LL | let _diag = dcx.struct_err(crate::fluent_generated::no_crate_example); + | ^^^^^^^^^^ | note: the lint level is defined here --> $DIR/diagnostics.rs:7:9 @@ -29,16 +29,16 @@ LL | #![deny(rustc::diagnostic_outside_of_impl)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: diagnostics should only be created in `IntoDiagnostic`/`AddToDiagnostic` impls - --> $DIR/diagnostics.rs:82:25 + --> $DIR/diagnostics.rs:82:21 | -LL | let _diag = handler.struct_err("untranslatable diagnostic"); - | ^^^^^^^^^^ +LL | let _diag = dcx.struct_err("untranslatable diagnostic"); + | ^^^^^^^^^^ error: diagnostics should be created using translatable messages - --> $DIR/diagnostics.rs:82:25 + --> $DIR/diagnostics.rs:82:21 | -LL | let _diag = handler.struct_err("untranslatable diagnostic"); - | ^^^^^^^^^^ +LL | let _diag = dcx.struct_err("untranslatable diagnostic"); + | ^^^^^^^^^^ error: aborting due to 5 previous errors diff --git a/tests/ui-fulldeps/stable-mir/check_abi.rs b/tests/ui-fulldeps/stable-mir/check_abi.rs new file mode 100644 index 00000000000..30b42bc3bfa --- /dev/null +++ b/tests/ui-fulldeps/stable-mir/check_abi.rs @@ -0,0 +1,143 @@ +// run-pass +//! Test information regarding type layout. + +// ignore-stage1 +// ignore-cross-compile +// ignore-remote +// ignore-windows-gnu mingw has troubles with linking https://github.com/rust-lang/rust/pull/116837 + +#![feature(rustc_private)] +#![feature(assert_matches)] +#![feature(control_flow_enum)] +#![feature(ascii_char, ascii_char_variants)] + +extern crate rustc_hir; +extern crate rustc_middle; +#[macro_use] +extern crate rustc_smir; +extern crate rustc_driver; +extern crate rustc_interface; +extern crate stable_mir; + +use rustc_middle::ty::TyCtxt; +use rustc_smir::rustc_internal; +use stable_mir::abi::{ArgAbi, CallConvention, FieldsShape, PassMode, VariantsShape}; +use stable_mir::mir::mono::Instance; +use stable_mir::{CrateDef, CrateItem, CrateItems, ItemKind}; +use std::assert_matches::assert_matches; +use std::convert::TryFrom; +use std::io::Write; +use std::ops::ControlFlow; + +const CRATE_NAME: &str = "input"; + +/// This function uses the Stable MIR APIs to get information about the test crate. +fn test_stable_mir(_tcx: TyCtxt<'_>) -> ControlFlow<()> { + // Find items in the local crate. + let items = stable_mir::all_local_items(); + + // Test fn_abi + let target_fn = *get_item(&items, (ItemKind::Fn, "fn_abi")).unwrap(); + let instance = Instance::try_from(target_fn).unwrap(); + let fn_abi = instance.fn_abi().unwrap(); + assert_eq!(fn_abi.conv, CallConvention::Rust); + assert_eq!(fn_abi.args.len(), 2); + + check_ignore(&fn_abi.args[0]); + check_primitive(&fn_abi.args[1]); + check_result(fn_abi.ret); + + // Test variadic function. + let variadic_fn = *get_item(&items, (ItemKind::Fn, "variadic_fn")).unwrap(); + check_variadic(variadic_fn); + + ControlFlow::Continue(()) +} + +/// Check the variadic function ABI: +/// ```no_run +/// pub unsafe extern "C" fn variadic_fn(n: usize, mut args: ...) -> usize { +/// 0 +/// } +/// ``` +fn check_variadic(variadic_fn: CrateItem) { + let instance = Instance::try_from(variadic_fn).unwrap(); + let abi = instance.fn_abi().unwrap(); + assert!(abi.c_variadic); + assert_eq!(abi.args.len(), 1); +} + +/// Check the argument to be ignored: `ignore: [u8; 0]`. +fn check_ignore(abi: &ArgAbi) { + assert!(abi.ty.kind().is_array()); + assert_eq!(abi.mode, PassMode::Ignore); + let layout = abi.layout.shape(); + assert!(layout.is_sized()); + assert!(layout.is_1zst()); +} + +/// Check the primitive argument: `primitive: char`. +fn check_primitive(abi: &ArgAbi) { + assert!(abi.ty.kind().is_char()); + assert_matches!(abi.mode, PassMode::Direct(_)); + let layout = abi.layout.shape(); + assert!(layout.is_sized()); + assert!(!layout.is_1zst()); + assert_matches!(layout.fields, FieldsShape::Primitive); +} + +/// Check the return value: `Result<usize, &str>`. +fn check_result(abi: ArgAbi) { + assert!(abi.ty.kind().is_enum()); + assert_matches!(abi.mode, PassMode::Indirect { .. }); + let layout = abi.layout.shape(); + assert!(layout.is_sized()); + assert_matches!(layout.fields, FieldsShape::Arbitrary { .. }); + assert_matches!(layout.variants, VariantsShape::Multiple { .. }) +} + +fn get_item<'a>( + items: &'a CrateItems, + item: (ItemKind, &str), +) -> Option<&'a stable_mir::CrateItem> { + items.iter().find(|crate_item| (item.0 == crate_item.kind()) && crate_item.name() == item.1) +} + +/// This test will generate and analyze a dummy crate using the stable mir. +/// For that, it will first write the dummy crate into a file. +/// Then it will create a `StableMir` using custom arguments and then +/// it will run the compiler. +fn main() { + let path = "alloc_input.rs"; + generate_input(&path).unwrap(); + let args = vec![ + "rustc".to_string(), + "--crate-type=lib".to_string(), + "--crate-name".to_string(), + CRATE_NAME.to_string(), + path.to_string(), + ]; + run!(args, tcx, test_stable_mir(tcx)).unwrap(); +} + +fn generate_input(path: &str) -> std::io::Result<()> { + let mut file = std::fs::File::create(path)?; + write!( + file, + r#" + #![feature(c_variadic)] + #![allow(unused_variables)] + + pub fn fn_abi(ignore: [u8; 0], primitive: char) -> Result<usize, &'static str> {{ + // We only care about the signature. + todo!() + }} + + + pub unsafe extern "C" fn variadic_fn(n: usize, mut args: ...) -> usize {{ + 0 + }} + "# + )?; + Ok(()) +} diff --git a/tests/ui-fulldeps/stable-mir/check_allocation.rs b/tests/ui-fulldeps/stable-mir/check_allocation.rs index 88c41537d9f..7ce3597206b 100644 --- a/tests/ui-fulldeps/stable-mir/check_allocation.rs +++ b/tests/ui-fulldeps/stable-mir/check_allocation.rs @@ -33,6 +33,7 @@ use std::ascii::Char; use std::assert_matches::assert_matches; use std::cmp::{max, min}; use std::collections::HashMap; +use std::ffi::CStr; use std::io::Write; use std::ops::ControlFlow; @@ -45,6 +46,7 @@ fn test_stable_mir(_tcx: TyCtxt<'_>) -> ControlFlow<()> { check_foo(*get_item(&items, (ItemKind::Static, "FOO")).unwrap()); check_bar(*get_item(&items, (ItemKind::Static, "BAR")).unwrap()); check_len(*get_item(&items, (ItemKind::Static, "LEN")).unwrap()); + check_cstr(*get_item(&items, (ItemKind::Static, "C_STR")).unwrap()); check_other_consts(*get_item(&items, (ItemKind::Fn, "other_consts")).unwrap()); check_type_id(*get_item(&items, (ItemKind::Fn, "check_type_id")).unwrap()); ControlFlow::Continue(()) @@ -86,6 +88,24 @@ fn check_bar(item: CrateItem) { assert_eq!(std::str::from_utf8(&allocation.raw_bytes().unwrap()), Ok("Bar")); } +/// Check the allocation data for static `C_STR`. +/// +/// ```no_run +/// static C_STR: &core::ffi::cstr = c"cstr"; +/// ``` +fn check_cstr(item: CrateItem) { + let def = StaticDef::try_from(item).unwrap(); + let alloc = def.eval_initializer().unwrap(); + assert_eq!(alloc.provenance.ptrs.len(), 1); + let deref = item.ty().kind().builtin_deref(true).unwrap(); + assert!(deref.ty.kind().is_cstr(), "Expected CStr, but got: {:?}", item.ty()); + + let alloc_id_0 = alloc.provenance.ptrs[0].1.0; + let GlobalAlloc::Memory(allocation) = GlobalAlloc::from(alloc_id_0) else { unreachable!() }; + assert_eq!(allocation.bytes.len(), 5); + assert_eq!(CStr::from_bytes_until_nul(&allocation.raw_bytes().unwrap()), Ok(c"cstr")); +} + /// Check the allocation data for constants used in `other_consts` function. fn check_other_consts(item: CrateItem) { // Instance body will force constant evaluation. @@ -189,7 +209,6 @@ fn check_len(item: CrateItem) { assert_eq!(alloc.read_uint(), Ok(2)); } -// Use internal API to find a function in a crate. fn get_item<'a>( items: &'a CrateItems, item: (ItemKind, &str), @@ -206,6 +225,7 @@ fn main() { generate_input(&path).unwrap(); let args = vec![ "rustc".to_string(), + "--edition=2021".to_string(), "--crate-name".to_string(), CRATE_NAME.to_string(), path.to_string(), @@ -224,6 +244,7 @@ fn generate_input(path: &str) -> std::io::Result<()> { static LEN: usize = 2; static FOO: [&str; 2] = ["hi", "there"]; static BAR: &str = "Bar"; + static C_STR: &std::ffi::CStr = c"cstr"; const NULL: *const u8 = std::ptr::null(); const TUPLE: (u32, u32) = (10, u32::MAX); diff --git a/tests/ui-fulldeps/stable-mir/check_defs.rs b/tests/ui-fulldeps/stable-mir/check_defs.rs index ad667511332..e9a2599d873 100644 --- a/tests/ui-fulldeps/stable-mir/check_defs.rs +++ b/tests/ui-fulldeps/stable-mir/check_defs.rs @@ -69,9 +69,9 @@ fn extract_elem_ty(ty: Ty) -> Ty { /// Check signature and type of `Vec::<u8>::new` and its generic version. fn test_vec_new(instance: mir::mono::Instance) { - let sig = instance.ty().kind().fn_sig().unwrap().skip_binder(); - assert_matches!(sig.inputs(), &[]); - let elem_ty = extract_elem_ty(sig.output()); + let sig = instance.fn_abi().unwrap(); + assert_eq!(&sig.args, &[]); + let elem_ty = extract_elem_ty(sig.ret.ty); assert_matches!(elem_ty.kind(), TyKind::RigidTy(RigidTy::Uint(UintTy::U8))); // Get the signature for Vec::<T>::new. diff --git a/tests/ui/closures/2229_closure_analysis/issue-118144.rs b/tests/ui/closures/2229_closure_analysis/issue-118144.rs new file mode 100644 index 00000000000..3e5d9f9739a --- /dev/null +++ b/tests/ui/closures/2229_closure_analysis/issue-118144.rs @@ -0,0 +1,16 @@ +// Regression test for ICE #118144 + +struct V(i32); + +fn func(func_arg: &mut V) { + || { + // Declaring `x` separately instead of using + // a destructuring binding like `let V(x) = ...` + // becaue only `V(x) = ...` triggers the ICE + let x; + V(x) = func_arg; //~ ERROR: mismatched types + func_arg.0 = 0; + }; +} + +fn main() {} diff --git a/tests/ui/closures/2229_closure_analysis/issue-118144.stderr b/tests/ui/closures/2229_closure_analysis/issue-118144.stderr new file mode 100644 index 00000000000..85cb5adc07e --- /dev/null +++ b/tests/ui/closures/2229_closure_analysis/issue-118144.stderr @@ -0,0 +1,11 @@ +error[E0308]: mismatched types + --> $DIR/issue-118144.rs:11:9 + | +LL | V(x) = func_arg; + | ^^^^ -------- this expression has type `&mut V` + | | + | expected `&mut V`, found `V` + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/coroutine/async-gen-yield-ty-is-unit.rs b/tests/ui/coroutine/async-gen-yield-ty-is-unit.rs new file mode 100644 index 00000000000..aac74d3eacb --- /dev/null +++ b/tests/ui/coroutine/async-gen-yield-ty-is-unit.rs @@ -0,0 +1,17 @@ +// compile-flags: --edition 2024 -Zunstable-options +// check-pass + +#![feature(async_iterator, gen_blocks, noop_waker)] + +use std::{async_iter::AsyncIterator, pin::pin, task::{Context, Waker}}; + +async gen fn gen_fn() -> &'static str { + yield "hello" +} + +pub fn main() { + let async_iterator = pin!(gen_fn()); + let waker = Waker::noop(); + let ctx = &mut Context::from_waker(&waker); + async_iterator.poll_next(ctx); +} diff --git a/tests/ui/coroutine/return-types-diverge.rs b/tests/ui/coroutine/return-types-diverge.rs new file mode 100644 index 00000000000..5f21c8cbf34 --- /dev/null +++ b/tests/ui/coroutine/return-types-diverge.rs @@ -0,0 +1,20 @@ +// compile-flags: --edition 2024 -Zunstable-options +// check-pass + +#![feature(gen_blocks)] + +fn diverge() -> ! { loop {} } + +async gen fn async_gen_fn() -> i32 { diverge() } + +gen fn gen_fn() -> i32 { diverge() } + +fn async_gen_block() { + async gen { yield (); diverge() }; +} + +fn gen_block() { + gen { yield (); diverge() }; +} + +fn main() {} diff --git a/tests/ui/coroutine/return-types.rs b/tests/ui/coroutine/return-types.rs new file mode 100644 index 00000000000..3543d6293f7 --- /dev/null +++ b/tests/ui/coroutine/return-types.rs @@ -0,0 +1,21 @@ +// compile-flags: --edition 2024 -Zunstable-options + +#![feature(gen_blocks)] + +async gen fn async_gen_fn() -> i32 { 0 } +//~^ ERROR mismatched types + +gen fn gen_fn() -> i32 { 0 } +//~^ ERROR mismatched types + +fn async_gen_block() { + async gen { yield (); 1 }; + //~^ ERROR mismatched types +} + +fn gen_block() { + gen { yield (); 1 }; + //~^ ERROR mismatched types +} + +fn main() {} diff --git a/tests/ui/coroutine/return-types.stderr b/tests/ui/coroutine/return-types.stderr new file mode 100644 index 00000000000..7be96e538d9 --- /dev/null +++ b/tests/ui/coroutine/return-types.stderr @@ -0,0 +1,31 @@ +error[E0308]: mismatched types + --> $DIR/return-types.rs:5:38 + | +LL | async gen fn async_gen_fn() -> i32 { 0 } + | --- ^ expected `()`, found integer + | | + | expected `()` because of return type + +error[E0308]: mismatched types + --> $DIR/return-types.rs:8:26 + | +LL | gen fn gen_fn() -> i32 { 0 } + | --- ^ expected `()`, found integer + | | + | expected `()` because of return type + +error[E0308]: mismatched types + --> $DIR/return-types.rs:12:27 + | +LL | async gen { yield (); 1 }; + | ^ expected `()`, found integer + +error[E0308]: mismatched types + --> $DIR/return-types.rs:17:21 + | +LL | gen { yield (); 1 }; + | ^ expected `()`, found integer + +error: aborting due to 4 previous errors + +For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/editions/edition-cstr-2015-2018.rs b/tests/ui/editions/edition-cstr-2015-2018.rs new file mode 100644 index 00000000000..4c35c48646a --- /dev/null +++ b/tests/ui/editions/edition-cstr-2015-2018.rs @@ -0,0 +1,62 @@ +macro_rules! construct { ($x:ident) => { $x"str" } } + //~^ ERROR expected one of `!`, `.`, `::`, `;`, `?`, `{`, `}`, or an operator, found `"str"` + //~| NOTE expected one of 8 possible tokens + +macro_rules! contain { () => { c"str" } } + //~^ ERROR expected one of `!`, `.`, `::`, `;`, `?`, `{`, `}`, or an operator, found `"str"` + //~| NOTE expected one of 8 possible tokens + //~| NOTE you may be trying to write a c-string literal + //~| NOTE c-string literals require Rust 2021 or later + //~| HELP pass `--edition 2021` to `rustc` + //~| NOTE for more on editions, read https://doc.rust-lang.org/edition-guide + +fn check_macro_construct() { + construct!(c); //~ NOTE in this expansion of construct! +} + +fn check_macro_contain() { + contain!(); + //~^ NOTE in this expansion of contain! + //~| NOTE in this expansion of contain! + //~| NOTE in this expansion of contain! + //~| NOTE in this expansion of contain! + //~| NOTE in this expansion of contain! +} + +fn check_basic() { + c"str"; + //~^ ERROR expected one of `!`, `.`, `::`, `;`, `?`, `{`, `}`, or an operator, found `"str"` + //~| NOTE expected one of 8 possible tokens + //~| NOTE you may be trying to write a c-string literal + //~| NOTE c-string literals require Rust 2021 or later + //~| HELP pass `--edition 2021` to `rustc` + //~| NOTE for more on editions, read https://doc.rust-lang.org/edition-guide +} + +fn check_craw() { + cr"str"; + //~^ ERROR expected one of `!`, `.`, `::`, `;`, `?`, `{`, `}`, or an operator, found `"str"` + //~| NOTE expected one of 8 possible tokens + //~| NOTE you may be trying to write a c-string literal + //~| NOTE c-string literals require Rust 2021 or later + //~| HELP pass `--edition 2021` to `rustc` + //~| NOTE for more on editions, read https://doc.rust-lang.org/edition-guide +} + +fn check_craw_hash() { + cr##"str"##; + //~^ ERROR expected one of `!`, `.`, `::`, `;`, `?`, `{`, `}`, or an operator, found `#` + //~| NOTE expected one of 8 possible tokens + //~| NOTE you may be trying to write a c-string literal + //~| NOTE c-string literals require Rust 2021 or later + //~| HELP pass `--edition 2021` to `rustc` + //~| NOTE for more on editions, read https://doc.rust-lang.org/edition-guide +} + +fn check_cstr_space() { + c "str"; + //~^ ERROR expected one of `!`, `.`, `::`, `;`, `?`, `{`, `}`, or an operator, found `"str"` + //~| NOTE expected one of 8 possible tokens +} + +fn main() {} diff --git a/tests/ui/editions/edition-cstr-2015-2018.stderr b/tests/ui/editions/edition-cstr-2015-2018.stderr new file mode 100644 index 00000000000..b864df308ef --- /dev/null +++ b/tests/ui/editions/edition-cstr-2015-2018.stderr @@ -0,0 +1,67 @@ +error: expected one of `!`, `.`, `::`, `;`, `?`, `{`, `}`, or an operator, found `"str"` + --> $DIR/edition-cstr-2015-2018.rs:27:6 + | +LL | c"str"; + | ^^^^^ expected one of 8 possible tokens + | + = note: you may be trying to write a c-string literal + = note: c-string literals require Rust 2021 or later + = help: pass `--edition 2021` to `rustc` + = note: for more on editions, read https://doc.rust-lang.org/edition-guide + +error: expected one of `!`, `.`, `::`, `;`, `?`, `{`, `}`, or an operator, found `"str"` + --> $DIR/edition-cstr-2015-2018.rs:37:7 + | +LL | cr"str"; + | ^^^^^ expected one of 8 possible tokens + | + = note: you may be trying to write a c-string literal + = note: c-string literals require Rust 2021 or later + = help: pass `--edition 2021` to `rustc` + = note: for more on editions, read https://doc.rust-lang.org/edition-guide + +error: expected one of `!`, `.`, `::`, `;`, `?`, `{`, `}`, or an operator, found `#` + --> $DIR/edition-cstr-2015-2018.rs:47:7 + | +LL | cr##"str"##; + | ^ expected one of 8 possible tokens + | + = note: you may be trying to write a c-string literal + = note: c-string literals require Rust 2021 or later + = help: pass `--edition 2021` to `rustc` + = note: for more on editions, read https://doc.rust-lang.org/edition-guide + +error: expected one of `!`, `.`, `::`, `;`, `?`, `{`, `}`, or an operator, found `"str"` + --> $DIR/edition-cstr-2015-2018.rs:57:7 + | +LL | c "str"; + | ^^^^^ expected one of 8 possible tokens + +error: expected one of `!`, `.`, `::`, `;`, `?`, `{`, `}`, or an operator, found `"str"` + --> $DIR/edition-cstr-2015-2018.rs:1:44 + | +LL | macro_rules! construct { ($x:ident) => { $x"str" } } + | ^^^^^ expected one of 8 possible tokens +... +LL | construct!(c); + | ------------- in this macro invocation + | + = note: this error originates in the macro `construct` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: expected one of `!`, `.`, `::`, `;`, `?`, `{`, `}`, or an operator, found `"str"` + --> $DIR/edition-cstr-2015-2018.rs:5:33 + | +LL | macro_rules! contain { () => { c"str" } } + | ^^^^^ expected one of 8 possible tokens +... +LL | contain!(); + | ---------- in this macro invocation + | + = note: you may be trying to write a c-string literal + = note: c-string literals require Rust 2021 or later + = help: pass `--edition 2021` to `rustc` + = note: for more on editions, read https://doc.rust-lang.org/edition-guide + = note: this error originates in the macro `contain` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: aborting due to 6 previous errors + diff --git a/tests/ui/entry-point/issue-118772.rs b/tests/ui/entry-point/issue-118772.rs new file mode 100644 index 00000000000..1a4173e1252 --- /dev/null +++ b/tests/ui/entry-point/issue-118772.rs @@ -0,0 +1,3 @@ +fn main(_: &i32) { //~ ERROR `main` function has wrong type + println!("Hello, world!"); +} diff --git a/tests/ui/entry-point/issue-118772.stderr b/tests/ui/entry-point/issue-118772.stderr new file mode 100644 index 00000000000..cc33427f59d --- /dev/null +++ b/tests/ui/entry-point/issue-118772.stderr @@ -0,0 +1,12 @@ +error[E0580]: `main` function has wrong type + --> $DIR/issue-118772.rs:1:1 + | +LL | fn main(_: &i32) { + | ^^^^^^^^^^^^^^^^ incorrect number of function parameters + | + = note: expected signature `fn()` + found signature `for<'a> fn(&'a i32)` + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0580`. diff --git a/tests/ui/hygiene/panic-location.run.stderr b/tests/ui/hygiene/panic-location.run.stderr index e0dc13c0c95..5c552411da7 100644 --- a/tests/ui/hygiene/panic-location.run.stderr +++ b/tests/ui/hygiene/panic-location.run.stderr @@ -1,3 +1,3 @@ -thread 'main' panicked at library/alloc/src/raw_vec.rs:545:5: +thread 'main' panicked at library/alloc/src/raw_vec.rs:571:5: capacity overflow note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace diff --git a/tests/ui/intrinsics/const-eval-select-bad.stderr b/tests/ui/intrinsics/const-eval-select-bad.stderr index bf91dc72cc1..85e22178c4a 100644 --- a/tests/ui/intrinsics/const-eval-select-bad.stderr +++ b/tests/ui/intrinsics/const-eval-select-bad.stderr @@ -16,20 +16,24 @@ LL | const_eval_select((), || {}, || {}); = note: expected a function item, found {closure@$DIR/const-eval-select-bad.rs:7:34: 7:36} = help: consult the documentation on `const_eval_select` for more information -error: this argument must be a function item +error[E0277]: expected a `FnOnce()` closure, found `{integer}` --> $DIR/const-eval-select-bad.rs:10:27 | LL | const_eval_select((), 42, 0xDEADBEEF); - | ^^ + | ----------------- ^^ expected an `FnOnce()` closure, found `{integer}` + | | + | required by a bound introduced by this call | - = note: expected a function item, found {integer} - = help: consult the documentation on `const_eval_select` for more information + = help: the trait `FnOnce<()>` is not implemented for `{integer}` + = note: wrap the `{integer}` in a closure with no arguments: `|| { /* code */ }` +note: required by a bound in `const_eval_select` + --> $SRC_DIR/core/src/intrinsics.rs:LL:COL error[E0277]: expected a `FnOnce()` closure, found `{integer}` - --> $DIR/const-eval-select-bad.rs:10:27 + --> $DIR/const-eval-select-bad.rs:10:31 | LL | const_eval_select((), 42, 0xDEADBEEF); - | ----------------- ^^ expected an `FnOnce()` closure, found `{integer}` + | ----------------- ^^^^^^^^^^ expected an `FnOnce()` closure, found `{integer}` | | | required by a bound introduced by this call | @@ -39,26 +43,22 @@ note: required by a bound in `const_eval_select` --> $SRC_DIR/core/src/intrinsics.rs:LL:COL error: this argument must be a function item - --> $DIR/const-eval-select-bad.rs:10:31 + --> $DIR/const-eval-select-bad.rs:10:27 | LL | const_eval_select((), 42, 0xDEADBEEF); - | ^^^^^^^^^^ + | ^^ | = note: expected a function item, found {integer} = help: consult the documentation on `const_eval_select` for more information -error[E0277]: expected a `FnOnce()` closure, found `{integer}` +error: this argument must be a function item --> $DIR/const-eval-select-bad.rs:10:31 | LL | const_eval_select((), 42, 0xDEADBEEF); - | ----------------- ^^^^^^^^^^ expected an `FnOnce()` closure, found `{integer}` - | | - | required by a bound introduced by this call + | ^^^^^^^^^^ | - = help: the trait `FnOnce<()>` is not implemented for `{integer}` - = note: wrap the `{integer}` in a closure with no arguments: `|| { /* code */ }` -note: required by a bound in `const_eval_select` - --> $SRC_DIR/core/src/intrinsics.rs:LL:COL + = note: expected a function item, found {integer} + = help: consult the documentation on `const_eval_select` for more information error[E0271]: expected `bar` to be a fn item that returns `i32`, but it returns `bool` --> $DIR/const-eval-select-bad.rs:32:34 diff --git a/tests/ui/issues/issue-22638.rs b/tests/ui/issues/issue-22638.rs index c2407227c2b..67fd147ae23 100644 --- a/tests/ui/issues/issue-22638.rs +++ b/tests/ui/issues/issue-22638.rs @@ -1,6 +1,7 @@ // build-fail // normalize-stderr-test: "<\{closure@.+`" -> "$$CLOSURE`" // normalize-stderr-test: ".nll/" -> "/" +// ignore-compare-mode-next-solver (hangs) #![allow(unused)] diff --git a/tests/ui/issues/issue-22638.stderr b/tests/ui/issues/issue-22638.stderr index a372078abd8..45290f6afe9 100644 --- a/tests/ui/issues/issue-22638.stderr +++ b/tests/ui/issues/issue-22638.stderr @@ -1,11 +1,11 @@ error: reached the recursion limit while instantiating `A::matches::$CLOSURE` - --> $DIR/issue-22638.rs:56:9 + --> $DIR/issue-22638.rs:57:9 | LL | a.matches(f) | ^^^^^^^^^^^^ | note: `A::matches` defined here - --> $DIR/issue-22638.rs:15:5 + --> $DIR/issue-22638.rs:16:5 | LL | pub fn matches<F: Fn()>(&self, f: &F) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/issues/issue-67552.rs b/tests/ui/issues/issue-67552.rs index 7336b873dd6..ec1997ccd5d 100644 --- a/tests/ui/issues/issue-67552.rs +++ b/tests/ui/issues/issue-67552.rs @@ -1,7 +1,6 @@ // build-fail // compile-flags: -Copt-level=0 // normalize-stderr-test: ".nll/" -> "/" -// ignore-compare-mode-next-solver (hangs) fn main() { rec(Empty); diff --git a/tests/ui/issues/issue-67552.stderr b/tests/ui/issues/issue-67552.stderr index 539bd45dbf1..1a8d7248b45 100644 --- a/tests/ui/issues/issue-67552.stderr +++ b/tests/ui/issues/issue-67552.stderr @@ -1,11 +1,11 @@ error: reached the recursion limit while instantiating `rec::<&mut &mut &mut &mut &mut ...>` - --> $DIR/issue-67552.rs:30:9 + --> $DIR/issue-67552.rs:29:9 | LL | rec(identity(&mut it)) | ^^^^^^^^^^^^^^^^^^^^^^ | note: `rec` defined here - --> $DIR/issue-67552.rs:23:1 + --> $DIR/issue-67552.rs:22:1 | LL | / fn rec<T>(mut it: T) LL | | where diff --git a/tests/ui/macros/issue-118786.rs b/tests/ui/macros/issue-118786.rs new file mode 100644 index 00000000000..84af3a65113 --- /dev/null +++ b/tests/ui/macros/issue-118786.rs @@ -0,0 +1,16 @@ +// compile-flags: --crate-type lib -O -C debug-assertions=yes + +// Regression test for issue 118786 + +macro_rules! make_macro { + ($macro_name:tt) => { + macro_rules! $macro_name { + //~^ ERROR macros that expand to items must be delimited with braces or followed by a semicolon + //~| ERROR macro expansion ignores token `{` and any following + //~| ERROR cannot find macro `macro_rules` in this scope + () => {} + } + } +} + +make_macro!((meow)); diff --git a/tests/ui/macros/issue-118786.stderr b/tests/ui/macros/issue-118786.stderr new file mode 100644 index 00000000000..ca3a40f31c1 --- /dev/null +++ b/tests/ui/macros/issue-118786.stderr @@ -0,0 +1,47 @@ +error: macros that expand to items must be delimited with braces or followed by a semicolon + --> $DIR/issue-118786.rs:7:22 + | +LL | macro_rules! $macro_name { + | ^^^^^^^^^^^ + | +help: change the delimiters to curly braces + | +LL | macro_rules! {} { + | ~ + +help: add a semicolon + | +LL | macro_rules! $macro_name; { + | + + +error: macro expansion ignores token `{` and any following + --> $DIR/issue-118786.rs:7:34 + | +LL | macro_rules! $macro_name { + | ^ +... +LL | make_macro!((meow)); + | ------------------- caused by the macro expansion here + | + = note: the usage of `make_macro!` is likely invalid in item context + +error: cannot find macro `macro_rules` in this scope + --> $DIR/issue-118786.rs:7:9 + | +LL | macro_rules! $macro_name { + | ^^^^^^^^^^^ +... +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 + | +LL | macro_rules! $macro_name { + | ^^^^^^^^^^^ +... +LL | make_macro!((meow)); + | ------------------- in this macro invocation + = note: this error originates in the macro `make_macro` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: aborting due to 3 previous errors + diff --git a/tests/ui/parser/bad-let-else-statement.rs b/tests/ui/parser/bad-let-else-statement.rs new file mode 100644 index 00000000000..7b927c89ba0 --- /dev/null +++ b/tests/ui/parser/bad-let-else-statement.rs @@ -0,0 +1,164 @@ +#![feature(inline_const)] +#![feature(yeet_expr)] +#![allow(incomplete_features)] // Necessary for now, while explicit_tail_calls is incomplete +#![feature(explicit_tail_calls)] + +fn a() { + let foo = { + 1 + } else { + //~^ ERROR right curly brace `}` before `else` in a `let...else` statement not allowed + return; + }; +} + +fn b() { + let foo = for i in 1..2 { + break; + } else { + //~^ ERROR `for...else` loops are not supported + return; + }; +} + +fn c() { + let foo = if true { + 1 + } else { + 0 + } else { + //~^ ERROR right curly brace `}` before `else` in a `let...else` statement not allowed + return; + }; +} + +fn d() { + let foo = loop { + break; + } else { + //~^ ERROR loop...else` loops are not supported + return; + }; +} + +fn e() { + let foo = match true { + true => 1, + false => 0 + } else { + //~^ ERROR right curly brace `}` before `else` in a `let...else` statement not allowed + return; + }; +} + +struct X {a: i32} +fn f() { + let foo = X { + a: 1 + } else { + //~^ ERROR right curly brace `}` before `else` in a `let...else` statement not allowed + return; + }; +} + +fn g() { + let foo = while false { + break; + } else { + //~^ ERROR `while...else` loops are not supported + return; + }; +} + +fn h() { + let foo = const { + 1 + } else { + //~^ ERROR right curly brace `}` before `else` in a `let...else` statement not allowed + return; + }; +} + +fn i() { + let foo = &{ + 1 + } else { + //~^ ERROR right curly brace `}` before `else` in a `let...else` statement not allowed + return; + }; +} + +fn j() { + let bar = 0; + let foo = bar = { + 1 + } else { + //~^ ERROR right curly brace `}` before `else` in a `let...else` statement not allowed + return; + }; +} + +fn k() { + let foo = 1 + { + 1 + } else { + //~^ ERROR right curly brace `}` before `else` in a `let...else` statement not allowed + return; + }; +} + +fn l() { + let foo = 1..{ + 1 + } else { + //~^ ERROR right curly brace `}` before `else` in a `let...else` statement not allowed + return; + }; +} + +fn m() { + let foo = return { + () + } else { + //~^ ERROR right curly brace `}` before `else` in a `let...else` statement not allowed + return; + }; +} + +fn n() { + let foo = -{ + 1 + } else { + //~^ ERROR right curly brace `}` before `else` in a `let...else` statement not allowed + return; + }; +} + +fn o() -> Result<(), ()> { + let foo = do yeet { + () + } else { + //~^ ERROR right curly brace `}` before `else` in a `let...else` statement not allowed + return Ok(()); + }; +} + +fn p() { + let foo = become { + () + } else { + //~^ ERROR right curly brace `}` before `else` in a `let...else` statement not allowed + return; + }; +} + +fn q() { + let foo = |x: i32| { + x + } else { + //~^ ERROR right curly brace `}` before `else` in a `let...else` statement not allowed + return; + }; +} + +fn main() {} diff --git a/tests/ui/parser/bad-let-else-statement.stderr b/tests/ui/parser/bad-let-else-statement.stderr new file mode 100644 index 00000000000..7cbda25e417 --- /dev/null +++ b/tests/ui/parser/bad-let-else-statement.stderr @@ -0,0 +1,232 @@ +error: right curly brace `}` before `else` in a `let...else` statement not allowed + --> $DIR/bad-let-else-statement.rs:9:5 + | +LL | } else { + | ^ + | +help: wrap the expression in parentheses + | +LL ~ let foo = ({ +LL | 1 +LL ~ }) else { + | + +error: `for...else` loops are not supported + --> $DIR/bad-let-else-statement.rs:18:7 + | +LL | let foo = for i in 1..2 { + | --- `else` is attached to this loop +LL | break; +LL | } else { + | _______^ +LL | | +LL | | return; +LL | | }; + | |_____^ + | + = note: consider moving this `else` clause to a separate `if` statement and use a `bool` variable to control if it should run + +error: right curly brace `}` before `else` in a `let...else` statement not allowed + --> $DIR/bad-let-else-statement.rs:29:5 + | +LL | } else { + | ^ + | +help: wrap the expression in parentheses + | +LL ~ let foo = (if true { +LL | 1 +LL | } else { +LL | 0 +LL ~ }) else { + | + +error: `loop...else` loops are not supported + --> $DIR/bad-let-else-statement.rs:38:7 + | +LL | let foo = loop { + | ---- `else` is attached to this loop +LL | break; +LL | } else { + | _______^ +LL | | +LL | | return; +LL | | }; + | |_____^ + | + = note: consider moving this `else` clause to a separate `if` statement and use a `bool` variable to control if it should run + +error: right curly brace `}` before `else` in a `let...else` statement not allowed + --> $DIR/bad-let-else-statement.rs:48:5 + | +LL | } else { + | ^ + | +help: wrap the expression in parentheses + | +LL ~ let foo = (match true { +LL | true => 1, +LL | false => 0 +LL ~ }) else { + | + +error: right curly brace `}` before `else` in a `let...else` statement not allowed + --> $DIR/bad-let-else-statement.rs:58:5 + | +LL | } else { + | ^ + | +help: wrap the expression in parentheses + | +LL ~ let foo = (X { +LL | a: 1 +LL ~ }) else { + | + +error: `while...else` loops are not supported + --> $DIR/bad-let-else-statement.rs:67:7 + | +LL | let foo = while false { + | ----- `else` is attached to this loop +LL | break; +LL | } else { + | _______^ +LL | | +LL | | return; +LL | | }; + | |_____^ + | + = note: consider moving this `else` clause to a separate `if` statement and use a `bool` variable to control if it should run + +error: right curly brace `}` before `else` in a `let...else` statement not allowed + --> $DIR/bad-let-else-statement.rs:76:5 + | +LL | } else { + | ^ + | +help: wrap the expression in parentheses + | +LL ~ let foo = (const { +LL | 1 +LL ~ }) else { + | + +error: right curly brace `}` before `else` in a `let...else` statement not allowed + --> $DIR/bad-let-else-statement.rs:85:5 + | +LL | } else { + | ^ + | +help: wrap the expression in parentheses + | +LL ~ let foo = &({ +LL | 1 +LL ~ }) else { + | + +error: right curly brace `}` before `else` in a `let...else` statement not allowed + --> $DIR/bad-let-else-statement.rs:95:5 + | +LL | } else { + | ^ + | +help: wrap the expression in parentheses + | +LL ~ let foo = bar = ({ +LL | 1 +LL ~ }) else { + | + +error: right curly brace `}` before `else` in a `let...else` statement not allowed + --> $DIR/bad-let-else-statement.rs:104:5 + | +LL | } else { + | ^ + | +help: wrap the expression in parentheses + | +LL ~ let foo = 1 + ({ +LL | 1 +LL ~ }) else { + | + +error: right curly brace `}` before `else` in a `let...else` statement not allowed + --> $DIR/bad-let-else-statement.rs:113:5 + | +LL | } else { + | ^ + | +help: wrap the expression in parentheses + | +LL ~ let foo = 1..({ +LL | 1 +LL ~ }) else { + | + +error: right curly brace `}` before `else` in a `let...else` statement not allowed + --> $DIR/bad-let-else-statement.rs:122:5 + | +LL | } else { + | ^ + | +help: wrap the expression in parentheses + | +LL ~ let foo = return ({ +LL | () +LL ~ }) else { + | + +error: right curly brace `}` before `else` in a `let...else` statement not allowed + --> $DIR/bad-let-else-statement.rs:131:5 + | +LL | } else { + | ^ + | +help: wrap the expression in parentheses + | +LL ~ let foo = -({ +LL | 1 +LL ~ }) else { + | + +error: right curly brace `}` before `else` in a `let...else` statement not allowed + --> $DIR/bad-let-else-statement.rs:140:5 + | +LL | } else { + | ^ + | +help: wrap the expression in parentheses + | +LL ~ let foo = do yeet ({ +LL | () +LL ~ }) else { + | + +error: right curly brace `}` before `else` in a `let...else` statement not allowed + --> $DIR/bad-let-else-statement.rs:149:5 + | +LL | } else { + | ^ + | +help: wrap the expression in parentheses + | +LL ~ let foo = become ({ +LL | () +LL ~ }) else { + | + +error: right curly brace `}` before `else` in a `let...else` statement not allowed + --> $DIR/bad-let-else-statement.rs:158:5 + | +LL | } else { + | ^ + | +help: wrap the expression in parentheses + | +LL ~ let foo = |x: i32| ({ +LL | x +LL ~ }) else { + | + +error: aborting due to 17 previous errors + diff --git a/tests/ui/parser/trait-item-with-defaultness-fail-semantic.rs b/tests/ui/parser/defaultness-invalid-places-fail-semantic.rs index f2d97b7bac3..bff53f66e19 100644 --- a/tests/ui/parser/trait-item-with-defaultness-fail-semantic.rs +++ b/tests/ui/parser/defaultness-invalid-places-fail-semantic.rs @@ -10,3 +10,7 @@ trait X { default fn f1(); //~ ERROR `default` is only allowed on items in trait impls default fn f2() {} //~ ERROR `default` is only allowed on items in trait impls } + +default const E: u8 = 0; //~ ERROR `default` is only allowed on items in trait impls +default type F = (); //~ ERROR `default` is only allowed on items in trait impls +default fn h() {} //~ ERROR `default` is only allowed on items in trait impls diff --git a/tests/ui/parser/trait-item-with-defaultness-fail-semantic.stderr b/tests/ui/parser/defaultness-invalid-places-fail-semantic.stderr index be858cd651d..41fad3a5de3 100644 --- a/tests/ui/parser/trait-item-with-defaultness-fail-semantic.stderr +++ b/tests/ui/parser/defaultness-invalid-places-fail-semantic.stderr @@ -1,5 +1,5 @@ error: `default` is only allowed on items in trait impls - --> $DIR/trait-item-with-defaultness-fail-semantic.rs:6:5 + --> $DIR/defaultness-invalid-places-fail-semantic.rs:6:5 | LL | default const A: u8; | -------^^^^^^^^^^^^^ @@ -7,7 +7,7 @@ LL | default const A: u8; | `default` because of this error: `default` is only allowed on items in trait impls - --> $DIR/trait-item-with-defaultness-fail-semantic.rs:7:5 + --> $DIR/defaultness-invalid-places-fail-semantic.rs:7:5 | LL | default const B: u8 = 0; | -------^^^^^^^^^^^^^^^^^ @@ -15,7 +15,7 @@ LL | default const B: u8 = 0; | `default` because of this error: `default` is only allowed on items in trait impls - --> $DIR/trait-item-with-defaultness-fail-semantic.rs:8:5 + --> $DIR/defaultness-invalid-places-fail-semantic.rs:8:5 | LL | default type D; | -------^^^^^^^^ @@ -23,7 +23,7 @@ LL | default type D; | `default` because of this error: `default` is only allowed on items in trait impls - --> $DIR/trait-item-with-defaultness-fail-semantic.rs:9:5 + --> $DIR/defaultness-invalid-places-fail-semantic.rs:9:5 | LL | default type C: Ord; | -------^^^^^^^^^^^^^ @@ -31,7 +31,7 @@ LL | default type C: Ord; | `default` because of this error: `default` is only allowed on items in trait impls - --> $DIR/trait-item-with-defaultness-fail-semantic.rs:10:5 + --> $DIR/defaultness-invalid-places-fail-semantic.rs:10:5 | LL | default fn f1(); | -------^^^^^^^^^ @@ -39,15 +39,39 @@ LL | default fn f1(); | `default` because of this error: `default` is only allowed on items in trait impls - --> $DIR/trait-item-with-defaultness-fail-semantic.rs:11:5 + --> $DIR/defaultness-invalid-places-fail-semantic.rs:11:5 | LL | default fn f2() {} | -------^^^^^^^^ | | | `default` because of this +error: `default` is only allowed on items in trait impls + --> $DIR/defaultness-invalid-places-fail-semantic.rs:14:1 + | +LL | default const E: u8 = 0; + | -------^^^^^^^^^^^^^^^^^ + | | + | `default` because of this + +error: `default` is only allowed on items in trait impls + --> $DIR/defaultness-invalid-places-fail-semantic.rs:15:1 + | +LL | default type F = (); + | -------^^^^^^^^^^^^^ + | | + | `default` because of this + +error: `default` is only allowed on items in trait impls + --> $DIR/defaultness-invalid-places-fail-semantic.rs:16:1 + | +LL | default fn h() {} + | -------^^^^^^^ + | | + | `default` because of this + warning: the feature `specialization` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/trait-item-with-defaultness-fail-semantic.rs:1:12 + --> $DIR/defaultness-invalid-places-fail-semantic.rs:1:12 | LL | #![feature(specialization)] | ^^^^^^^^^^^^^^ @@ -56,5 +80,5 @@ LL | #![feature(specialization)] = help: consider using `min_specialization` instead, which is more stable and complete = note: `#[warn(incomplete_features)]` on by default -error: aborting due to 6 previous errors; 1 warning emitted +error: aborting due to 9 previous errors; 1 warning emitted diff --git a/tests/ui/privacy/unresolved-trait-impl-item.rs b/tests/ui/privacy/unresolved-trait-impl-item.rs new file mode 100644 index 00000000000..fea7c462a8e --- /dev/null +++ b/tests/ui/privacy/unresolved-trait-impl-item.rs @@ -0,0 +1,15 @@ +// edition:2018 + +trait MyTrait { + async fn resolved(&self); + const RESOLVED_WRONG: u8 = 0; +} + +impl MyTrait for i32 { + async fn resolved(&self) {} + + async fn unresolved(&self) {} //~ ERROR method `unresolved` is not a member of trait `MyTrait` + async fn RESOLVED_WRONG() {} //~ ERROR doesn't match its trait `MyTrait` +} + +fn main() {} diff --git a/tests/ui/privacy/unresolved-trait-impl-item.stderr b/tests/ui/privacy/unresolved-trait-impl-item.stderr new file mode 100644 index 00000000000..588e47c26bc --- /dev/null +++ b/tests/ui/privacy/unresolved-trait-impl-item.stderr @@ -0,0 +1,22 @@ +error[E0407]: method `unresolved` is not a member of trait `MyTrait` + --> $DIR/unresolved-trait-impl-item.rs:11:5 + | +LL | async fn unresolved(&self) {} + | ^^^^^^^^^----------^^^^^^^^^^ + | | | + | | help: there is an associated function with a similar name: `resolved` + | not a member of trait `MyTrait` + +error[E0324]: item `RESOLVED_WRONG` is an associated method, which doesn't match its trait `MyTrait` + --> $DIR/unresolved-trait-impl-item.rs:12:5 + | +LL | const RESOLVED_WRONG: u8 = 0; + | ----------------------------- item in trait +... +LL | async fn RESOLVED_WRONG() {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ does not match trait + +error: aborting due to 2 previous errors + +Some errors have detailed explanations: E0324, E0407. +For more information about an error, try `rustc --explain E0324`. diff --git a/tests/ui/recursion/issue-95134.rs b/tests/ui/recursion/issue-95134.rs index 7ee31d85c2b..2f1cffa2fa9 100644 --- a/tests/ui/recursion/issue-95134.rs +++ b/tests/ui/recursion/issue-95134.rs @@ -3,7 +3,6 @@ // compile-flags: -Copt-level=0 // dont-check-failure-status // dont-check-compiler-stderr -// ignore-compare-mode-next-solver (hangs) pub fn encode_num<Writer: ExampleWriter>(n: u32, mut writer: Writer) -> Result<(), Writer::Error> { if n > 15 { diff --git a/tests/ui/rfcs/rfc-2361-dbg-macro/dbg-macro-expected-behavior.run.stderr b/tests/ui/rfcs/rfc-2361-dbg-macro/dbg-macro-expected-behavior.run.stderr index 1a26f34a52d..2c018ca875d 100644 --- a/tests/ui/rfcs/rfc-2361-dbg-macro/dbg-macro-expected-behavior.run.stderr +++ b/tests/ui/rfcs/rfc-2361-dbg-macro/dbg-macro-expected-behavior.run.stderr @@ -1,28 +1,28 @@ -[$DIR/dbg-macro-expected-behavior.rs:22] Unit = Unit -[$DIR/dbg-macro-expected-behavior.rs:23] a = Unit -[$DIR/dbg-macro-expected-behavior.rs:29] Point { x: 42, y: 24 } = Point { +[$DIR/dbg-macro-expected-behavior.rs:22:19] Unit = Unit +[$DIR/dbg-macro-expected-behavior.rs:23:19] a = Unit +[$DIR/dbg-macro-expected-behavior.rs:29:24] Point { x: 42, y: 24 } = Point { x: 42, y: 24, } -[$DIR/dbg-macro-expected-behavior.rs:30] b = Point { +[$DIR/dbg-macro-expected-behavior.rs:30:24] b = Point { x: 42, y: 24, } -[$DIR/dbg-macro-expected-behavior.rs:38] -[$DIR/dbg-macro-expected-behavior.rs:42] &a = NoCopy( +[$DIR/dbg-macro-expected-behavior.rs:38:17] +[$DIR/dbg-macro-expected-behavior.rs:42:27] &a = NoCopy( 1337, ) -[$DIR/dbg-macro-expected-behavior.rs:42] dbg!(&a) = NoCopy( +[$DIR/dbg-macro-expected-behavior.rs:42:22] dbg!(&a) = NoCopy( 1337, ) -[$DIR/dbg-macro-expected-behavior.rs:47] f(&42) = 42 +[$DIR/dbg-macro-expected-behavior.rs:47:18] f(&42) = 42 before -[$DIR/dbg-macro-expected-behavior.rs:52] { foo += 1; eprintln!("before"); 7331 } = 7331 -[$DIR/dbg-macro-expected-behavior.rs:60] ("Yeah",) = ( +[$DIR/dbg-macro-expected-behavior.rs:52:22] { foo += 1; eprintln!("before"); 7331 } = 7331 +[$DIR/dbg-macro-expected-behavior.rs:60:27] ("Yeah",) = ( "Yeah", ) -[$DIR/dbg-macro-expected-behavior.rs:63] 1 = 1 -[$DIR/dbg-macro-expected-behavior.rs:63] 2 = 2 -[$DIR/dbg-macro-expected-behavior.rs:67] 1u8 = 1 -[$DIR/dbg-macro-expected-behavior.rs:67] 2u32 = 2 -[$DIR/dbg-macro-expected-behavior.rs:67] "Yeah" = "Yeah" +[$DIR/dbg-macro-expected-behavior.rs:63:29] 1 = 1 +[$DIR/dbg-macro-expected-behavior.rs:63:29] 2 = 2 +[$DIR/dbg-macro-expected-behavior.rs:67:37] 1u8 = 1 +[$DIR/dbg-macro-expected-behavior.rs:67:37] 2u32 = 2 +[$DIR/dbg-macro-expected-behavior.rs:67:37] "Yeah" = "Yeah" diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/minicore.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/minicore.rs index 2a2e8cec3f0..59fb48e794c 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/minicore.rs +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/minicore.rs @@ -1,12 +1,13 @@ // check-pass #![crate_type = "lib"] -#![feature(no_core, lang_items, unboxed_closures, auto_traits, intrinsics, rustc_attrs)] +#![feature(no_core, lang_items, unboxed_closures, auto_traits, intrinsics, rustc_attrs, staged_api)] #![feature(fundamental)] #![feature(const_trait_impl, effects, const_mut_refs)] #![allow(internal_features)] #![no_std] #![no_core] +#![stable(feature = "minicore", since = "1.0.0")] #[lang = "sized"] trait Sized {} @@ -82,6 +83,7 @@ trait FnMut<Args: Tuple>: ~const FnOnce<Args> { #[lang = "fn_once"] #[rustc_paren_sugar] trait FnOnce<Args: Tuple> { + #[lang = "fn_once_output"] type Output; extern "rust-call" fn call_once(self, args: Args) -> Self::Output; @@ -93,7 +95,7 @@ struct ConstFnMutClosure<CapturedData, Function> { } #[lang = "tuple_trait"] -pub trait Tuple {} +trait Tuple {} macro_rules! impl_fn_mut_tuple { ($($var:ident)*) => { @@ -509,3 +511,17 @@ trait StructuralPartialEq {} trait StructuralEq {} const fn drop<T: ~const Destruct>(_: T) {} + +extern "rust-intrinsic" { + #[rustc_const_stable(feature = "const_eval_select", since = "1.0.0")] + fn const_eval_select<ARG: Tuple, F, G, RET>( + arg: ARG, + called_in_const: F, + called_at_rt: G, + ) -> RET + /* where clauses enforced by built-in method confirmation: + where + F: const FnOnce<Arg, Output = RET>, + G: FnOnce<Arg, Output = RET>, + */; +} diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/tilde-const-invalid-places.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/tilde-const-invalid-places.rs index bbe1194f7a3..5ecb75094f0 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/tilde-const-invalid-places.rs +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/tilde-const-invalid-places.rs @@ -52,4 +52,7 @@ trait Child1 where Self: ~const Trait {} //~ ERROR `~const` is not allowed // non-const impl impl<T: ~const Trait> Trait for T {} //~ ERROR `~const` is not allowed +// inherent impl (regression test for issue #117004) +impl<T: ~const Trait> Struct<T> {} //~ ERROR `~const` is not allowed + fn main() {} diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/tilde-const-invalid-places.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/tilde-const-invalid-places.stderr index c6e18924fd8..497ec5bcf84 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/tilde-const-invalid-places.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/tilde-const-invalid-places.stderr @@ -194,6 +194,18 @@ note: this impl is not `const`, so it cannot have `~const` trait bounds LL | impl<T: ~const Trait> Trait for T {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +error: `~const` is not allowed here + --> $DIR/tilde-const-invalid-places.rs:56:9 + | +LL | impl<T: ~const Trait> Struct<T> {} + | ^^^^^^ + | +note: inherent impls cannot have `~const` trait bounds + --> $DIR/tilde-const-invalid-places.rs:56:1 + | +LL | impl<T: ~const Trait> Struct<T> {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + error[E0658]: generic const items are experimental --> $DIR/tilde-const-invalid-places.rs:19:15 | @@ -239,6 +251,6 @@ LL | type Type<T: ~const Trait> = (); = note: see issue #8995 <https://github.com/rust-lang/rust/issues/8995> for more information = help: add `#![feature(inherent_associated_types)]` to the crate attributes to enable -error: aborting due to 26 previous errors +error: aborting due to 27 previous errors For more information about this error, try `rustc --explain E0658`. diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/tilde_const_on_impl_bound.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/tilde_const_on_impl_bound.rs index fbdc3a4f370..bfd9fe42e67 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/tilde_const_on_impl_bound.rs +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/tilde_const_on_impl_bound.rs @@ -1,5 +1,4 @@ -// known-bug: #110395 -// FIXME check-pass +// check-pass #![feature(const_trait_impl, effects)] #[const_trait] @@ -9,8 +8,8 @@ trait Foo { struct Bar<T>(T); -impl<T: ~const Foo> Bar<T> { - const fn foo(&self) { +impl<T> Bar<T> { + const fn foo(&self) where T: ~const Foo { self.0.foo() } } diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/tilde_const_on_impl_bound.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/tilde_const_on_impl_bound.stderr deleted file mode 100644 index 0925bfa7e57..00000000000 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/tilde_const_on_impl_bound.stderr +++ /dev/null @@ -1,12 +0,0 @@ -error[E0308]: mismatched types - --> $DIR/tilde_const_on_impl_bound.rs:14:9 - | -LL | self.0.foo() - | ^^^^^^^^^^^^ expected `host`, found `true` - | - = note: expected constant `host` - found constant `true` - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/traits/issue-117794.rs b/tests/ui/traits/issue-117794.rs new file mode 100644 index 00000000000..a66d6eb10ed --- /dev/null +++ b/tests/ui/traits/issue-117794.rs @@ -0,0 +1,10 @@ +trait Foo {} + +trait T { + fn a(&self) -> impl Foo { + self.b(|| 0) + //~^ ERROR no method named `b` found for reference `&Self` in the current scope + } +} + +fn main() {} diff --git a/tests/ui/traits/issue-117794.stderr b/tests/ui/traits/issue-117794.stderr new file mode 100644 index 00000000000..af63b47f07d --- /dev/null +++ b/tests/ui/traits/issue-117794.stderr @@ -0,0 +1,9 @@ +error[E0599]: no method named `b` found for reference `&Self` in the current scope + --> $DIR/issue-117794.rs:5:14 + | +LL | self.b(|| 0) + | ^ help: there is a method with a similar name: `a` + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0599`. diff --git a/tests/ui/traits/issue-90662-projection-caching.rs b/tests/ui/traits/issue-90662-projection-caching.rs index 879f30071bf..e08ab53fbb0 100644 --- a/tests/ui/traits/issue-90662-projection-caching.rs +++ b/tests/ui/traits/issue-90662-projection-caching.rs @@ -1,7 +1,15 @@ +// revisions: old next +//[next] compile-flags: -Znext-solver=coherence // check-pass // Regression test for issue #90662 -// Tests that projection caching does not cause a spurious error +// Tests that projection caching does not cause a spurious error. +// Coherence relies on the following overflowing goal to still constrain +// `?0` to `dyn Service`. +// +// Projection(<ServiceImpl as Provider<TestModule>>::Interface. ?0) +// +// cc https://github.com/rust-lang/trait-system-refactor-initiative/issues/70. trait HasProvider<T: ?Sized> {} trait Provider<M> { diff --git a/tests/ui/traits/next-solver/alias-bound-unsound.rs b/tests/ui/traits/next-solver/alias-bound-unsound.rs index 565bfe1186e..4e279a84a33 100644 --- a/tests/ui/traits/next-solver/alias-bound-unsound.rs +++ b/tests/ui/traits/next-solver/alias-bound-unsound.rs @@ -23,7 +23,7 @@ fn main() { let x = String::from("hello, world"); drop(<() as Foo>::copy_me(&x)); //~^ ERROR overflow evaluating the requirement `<() as Foo>::Item: Sized` - //~| ERROR overflow evaluating the requirement `<() as Foo>::Item normalizes-to _` + //~| ERROR overflow evaluating the requirement `<() as Foo>::Item == _` //~| ERROR overflow evaluating the requirement `<() as Foo>::Item well-formed` //~| ERROR overflow evaluating the requirement `String <: <() as Foo>::Item` //~| ERROR overflow evaluating the requirement `&<() as Foo>::Item well-formed` diff --git a/tests/ui/traits/next-solver/alias-bound-unsound.stderr b/tests/ui/traits/next-solver/alias-bound-unsound.stderr index b09c22f3f41..ac3f19b3fe6 100644 --- a/tests/ui/traits/next-solver/alias-bound-unsound.stderr +++ b/tests/ui/traits/next-solver/alias-bound-unsound.stderr @@ -19,7 +19,7 @@ LL | drop(<() as Foo>::copy_me(&x)); | = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`alias_bound_unsound`) -error[E0275]: overflow evaluating the requirement `<() as Foo>::Item normalizes-to _` +error[E0275]: overflow evaluating the requirement `<() as Foo>::Item == _` --> $DIR/alias-bound-unsound.rs:24:10 | LL | drop(<() as Foo>::copy_me(&x)); @@ -59,7 +59,6 @@ LL | drop(<() as Foo>::copy_me(&x)); | ^^^^^^^^^^^^^^^^^^^^^^^^ | = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`alias_bound_unsound`) - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error: aborting due to 7 previous errors diff --git a/tests/ui/traits/next-solver/coerce-ambig-alias-to-rigid-alias.rs b/tests/ui/traits/next-solver/coerce-ambig-alias-to-rigid-alias.rs new file mode 100644 index 00000000000..bcb48b5acc7 --- /dev/null +++ b/tests/ui/traits/next-solver/coerce-ambig-alias-to-rigid-alias.rs @@ -0,0 +1,15 @@ +// compile-flags: -Znext-solver +// check-pass + +trait Trait { + type Assoc; +} + +fn call<T: Trait>(_: <T as Trait>::Assoc, _: T) {} + +fn foo<T: Trait>(rigid: <T as Trait>::Assoc, t: T) { + // Check that we can coerce `<?0 as Trait>::Assoc` to `<T as Trait>::Assoc`. + call::<_ /* ?0 */>(rigid, t); +} + +fn main() {} diff --git a/tests/ui/traits/next-solver/object-unsafety.rs b/tests/ui/traits/next-solver/object-unsafety.rs index 8aae7217398..cfa53948b97 100644 --- a/tests/ui/traits/next-solver/object-unsafety.rs +++ b/tests/ui/traits/next-solver/object-unsafety.rs @@ -13,7 +13,6 @@ pub fn copy_any<T>(t: &T) -> T { //~^ ERROR the type `&<dyn Setup<From = T> as Setup>::From` is not well-formed //~| ERROR the trait bound `dyn Setup<From = T>: Setup` is not satisfied //~| ERROR mismatched types - //~| ERROR mismatched types //~| ERROR the type `<dyn Setup<From = T> as Setup>::From` is not well-formed //~| ERROR the size for values of type `<dyn Setup<From = T> as Setup>::From` cannot be known at compilation time diff --git a/tests/ui/traits/next-solver/object-unsafety.stderr b/tests/ui/traits/next-solver/object-unsafety.stderr index 914a8f9d4c5..ee38c256e5f 100644 --- a/tests/ui/traits/next-solver/object-unsafety.stderr +++ b/tests/ui/traits/next-solver/object-unsafety.stderr @@ -36,20 +36,6 @@ note: function defined here LL | fn copy<U: Setup + ?Sized>(from: &U::From) -> U::From { | ^^^^ -------------- -error[E0308]: mismatched types - --> $DIR/object-unsafety.rs:12:5 - | -LL | pub fn copy_any<T>(t: &T) -> T { - | - - expected `T` because of return type - | | - | expected this type parameter -LL | copy::<dyn Setup<From=T>>(t) - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ types differ - | - = note: expected type parameter `T` - found associated type `<dyn Setup<From = T> as Setup>::From` - = note: you might be missing a type parameter or trait bound - error: the type `<dyn Setup<From = T> as Setup>::From` is not well-formed --> $DIR/object-unsafety.rs:12:5 | @@ -72,7 +58,7 @@ help: consider further restricting the associated type LL | pub fn copy_any<T>(t: &T) -> T where <dyn Setup<From = T> as Setup>::From: Sized { | +++++++++++++++++++++++++++++++++++++++++++++++++ -error: aborting due to 6 previous errors +error: aborting due to 5 previous errors Some errors have detailed explanations: E0277, E0308. For more information about an error, try `rustc --explain E0277`. diff --git a/tests/ui/traits/next-solver/overflow/recursion-limit-normalizes-to-constraints.rs b/tests/ui/traits/next-solver/overflow/recursion-limit-normalizes-to-constraints.rs new file mode 100644 index 00000000000..03ef93dc233 --- /dev/null +++ b/tests/ui/traits/next-solver/overflow/recursion-limit-normalizes-to-constraints.rs @@ -0,0 +1,25 @@ +// compile-flags: -Znext-solver=coherence +// check-pass + +// A regression test for trait-system-refactor-initiative#70. + +trait Trait { + type Assoc; +} + +struct W<T: ?Sized>(*mut T); +impl<T: ?Sized> Trait for W<W<T>> +where + W<T>: Trait, +{ + type Assoc = (); +} + +trait NoOverlap {} +impl<T: Trait<Assoc = u32>> NoOverlap for T {} +// `Projection(<W<_> as Trait>::Assoc, u32)` should result in error even +// though applying the impl results in overflow. This is necessary to match +// the behavior of the old solver. +impl<T: ?Sized> NoOverlap for W<T> {} + +fn main() {} diff --git a/tests/ui/type-alias-impl-trait/self-referential-3.rs b/tests/ui/type-alias-impl-trait/self-referential-3.rs index 18f09b54867..922ac662071 100644 --- a/tests/ui/type-alias-impl-trait/self-referential-3.rs +++ b/tests/ui/type-alias-impl-trait/self-referential-3.rs @@ -1,3 +1,5 @@ +// ignore-compare-mode-next-solver (hangs) + #![feature(type_alias_impl_trait)] type Bar<'a, 'b> = impl PartialEq<Bar<'a, 'b>> + std::fmt::Debug; diff --git a/tests/ui/type-alias-impl-trait/self-referential-3.stderr b/tests/ui/type-alias-impl-trait/self-referential-3.stderr index 15ebcdafca6..32eac622e51 100644 --- a/tests/ui/type-alias-impl-trait/self-referential-3.stderr +++ b/tests/ui/type-alias-impl-trait/self-referential-3.stderr @@ -1,5 +1,5 @@ error[E0277]: can't compare `&i32` with `Bar<'a, 'b>` - --> $DIR/self-referential-3.rs:5:31 + --> $DIR/self-referential-3.rs:7:31 | LL | fn bar<'a, 'b>(i: &'a i32) -> Bar<'a, 'b> { | ^^^^^^^^^^^ no implementation for `&i32 == Bar<'a, 'b>` diff --git a/tests/ui/type-alias-impl-trait/self-referential-4.rs b/tests/ui/type-alias-impl-trait/self-referential-4.rs index 36742c8ad57..caa9e33bad0 100644 --- a/tests/ui/type-alias-impl-trait/self-referential-4.rs +++ b/tests/ui/type-alias-impl-trait/self-referential-4.rs @@ -1,3 +1,5 @@ +// ignore-compare-mode-next-solver (hangs) + #![feature(type_alias_impl_trait)] type Bar<'a, 'b> = impl PartialEq<Bar<'b, 'static>> + std::fmt::Debug; diff --git a/tests/ui/type-alias-impl-trait/self-referential-4.stderr b/tests/ui/type-alias-impl-trait/self-referential-4.stderr index 98c762e3d38..e7f9e232a27 100644 --- a/tests/ui/type-alias-impl-trait/self-referential-4.stderr +++ b/tests/ui/type-alias-impl-trait/self-referential-4.stderr @@ -1,5 +1,5 @@ error[E0277]: can't compare `&i32` with `Bar<'b, 'static>` - --> $DIR/self-referential-4.rs:5:31 + --> $DIR/self-referential-4.rs:7:31 | LL | fn bar<'a, 'b>(i: &'a i32) -> Bar<'a, 'b> { | ^^^^^^^^^^^ no implementation for `&i32 == Bar<'b, 'static>` @@ -10,7 +10,7 @@ LL | i = help: the trait `PartialEq` is implemented for `i32` error[E0277]: can't compare `&i32` with `Foo<'static, 'b>` - --> $DIR/self-referential-4.rs:11:31 + --> $DIR/self-referential-4.rs:13:31 | LL | fn foo<'a, 'b>(i: &'a i32) -> Foo<'a, 'b> { | ^^^^^^^^^^^ no implementation for `&i32 == Foo<'static, 'b>` @@ -21,7 +21,7 @@ LL | i = help: the trait `PartialEq` is implemented for `i32` error[E0277]: can't compare `&i32` with `Moo<'static, 'a>` - --> $DIR/self-referential-4.rs:17:31 + --> $DIR/self-referential-4.rs:19:31 | LL | fn moo<'a, 'b>(i: &'a i32) -> Moo<'a, 'b> { | ^^^^^^^^^^^ no implementation for `&i32 == Moo<'static, 'a>` diff --git a/tests/ui/type-alias-impl-trait/self-referential.rs b/tests/ui/type-alias-impl-trait/self-referential.rs index 34b7c24df9f..0900d7279ca 100644 --- a/tests/ui/type-alias-impl-trait/self-referential.rs +++ b/tests/ui/type-alias-impl-trait/self-referential.rs @@ -1,3 +1,5 @@ +// ignore-compare-mode-next-solver (hangs) + #![feature(type_alias_impl_trait)] type Bar<'a, 'b> = impl PartialEq<Bar<'b, 'a>> + std::fmt::Debug; diff --git a/tests/ui/type-alias-impl-trait/self-referential.stderr b/tests/ui/type-alias-impl-trait/self-referential.stderr index 9a17d495b62..27506b8d06f 100644 --- a/tests/ui/type-alias-impl-trait/self-referential.stderr +++ b/tests/ui/type-alias-impl-trait/self-referential.stderr @@ -1,5 +1,5 @@ error[E0277]: can't compare `&i32` with `Bar<'b, 'a>` - --> $DIR/self-referential.rs:5:31 + --> $DIR/self-referential.rs:7:31 | LL | fn bar<'a, 'b>(i: &'a i32) -> Bar<'a, 'b> { | ^^^^^^^^^^^ no implementation for `&i32 == Bar<'b, 'a>` @@ -11,7 +11,7 @@ LL | i = help: the trait `PartialEq` is implemented for `i32` error[E0277]: can't compare `&i32` with `(i32, Foo<'a, 'b>::{opaque#0})` - --> $DIR/self-referential.rs:12:31 + --> $DIR/self-referential.rs:14:31 | LL | fn foo<'a, 'b>(i: &'a i32) -> Foo<'a, 'b> { | ^^^^^^^^^^^ no implementation for `&i32 == (i32, Foo<'a, 'b>::{opaque#0})` @@ -23,7 +23,7 @@ LL | (42, i) = help: the trait `PartialEq` is implemented for `i32` error[E0277]: can't compare `&i32` with `(i32, Moo<'b, 'a>::{opaque#0})` - --> $DIR/self-referential.rs:19:31 + --> $DIR/self-referential.rs:21:31 | LL | fn moo<'a, 'b>(i: &'a i32) -> Moo<'a, 'b> { | ^^^^^^^^^^^ no implementation for `&i32 == (i32, Moo<'b, 'a>::{opaque#0})` |
