diff options
Diffstat (limited to 'tests')
410 files changed, 7673 insertions, 2683 deletions
diff --git a/tests/codegen/issues/issue-115385-llvm-jump-threading.rs b/tests/codegen/issues/issue-115385-llvm-jump-threading.rs new file mode 100644 index 00000000000..142e3596d96 --- /dev/null +++ b/tests/codegen/issues/issue-115385-llvm-jump-threading.rs @@ -0,0 +1,46 @@ +// compile-flags: -O -Ccodegen-units=1 + +#![crate_type = "lib"] + +#[repr(i64)] +pub enum Boolean { + False = 0, + True = 1, +} + +impl Clone for Boolean { + fn clone(&self) -> Self { + *self + } +} + +impl Copy for Boolean {} + +extern "C" { + fn set_value(foo: *mut i64); + fn bar(); +} + +pub fn foo(x: bool) { + let mut foo = core::mem::MaybeUninit::<i64>::uninit(); + unsafe { + set_value(foo.as_mut_ptr()); + } + + if x { + let l1 = unsafe { *foo.as_mut_ptr().cast::<Boolean>() }; + if matches!(l1, Boolean::False) { + unsafe { + *foo.as_mut_ptr() = 0; + } + } + } + + let l2 = unsafe { *foo.as_mut_ptr() }; + if l2 == 2 { + // CHECK: call void @bar + unsafe { + bar(); + } + } +} diff --git a/tests/codegen/sanitizer/kcfi-add-kcfi-flag.rs b/tests/codegen/sanitizer/kcfi-add-kcfi-flag.rs index c2eb852aec3..6d466b93c40 100644 --- a/tests/codegen/sanitizer/kcfi-add-kcfi-flag.rs +++ b/tests/codegen/sanitizer/kcfi-add-kcfi-flag.rs @@ -1,9 +1,20 @@ // Verifies that "kcfi" module flag is added. // -// needs-sanitizer-kcfi +// revisions: aarch64 x86_64 +// [aarch64] compile-flags: --target aarch64-unknown-none +// [aarch64] needs-llvm-components: aarch64 +// [x86_64] compile-flags: --target x86_64-unknown-none +// [x86_64] needs-llvm-components: x86 // compile-flags: -Ctarget-feature=-crt-static -Zsanitizer=kcfi +#![feature(no_core, lang_items)] #![crate_type="lib"] +#![no_core] + +#[lang="sized"] +trait Sized { } +#[lang="copy"] +trait Copy { } pub fn foo() { } diff --git a/tests/coverage-map/status-quo/closure.cov-map b/tests/coverage-map/status-quo/closure.cov-map index f3a32f091a9..7dbf6ec834d 100644 --- a/tests/coverage-map/status-quo/closure.cov-map +++ b/tests/coverage-map/status-quo/closure.cov-map @@ -1,5 +1,5 @@ Function name: closure::main -Raw bytes (170): 0x[01, 01, 17, 01, 00, 01, 00, 01, 00, 01, 00, 01, 00, 01, 00, 01, 00, 01, 00, 01, 00, 01, 00, 01, 00, 01, 00, 01, 00, 01, 00, 01, 00, 01, 00, 01, 00, 01, 00, 01, 00, 01, 00, 01, 05, 05, 5a, 01, 05, 18, 01, 08, 01, 0f, 0d, 03, 16, 0e, 06, 0a, 07, 10, 05, 13, 0d, 0b, 1a, 0e, 08, 09, 0f, 10, 05, 0e, 09, 13, 16, 05, 0d, 18, 17, 19, 09, 01, 21, 1b, 04, 09, 00, 29, 1f, 01, 09, 00, 2d, 23, 01, 09, 00, 24, 27, 05, 09, 00, 24, 2b, 02, 09, 00, 21, 2f, 04, 09, 00, 21, 33, 04, 09, 00, 28, 37, 09, 09, 00, 32, 3b, 04, 09, 00, 33, 3f, 07, 09, 00, 4b, 43, 08, 09, 01, 09, 47, 0a, 09, 01, 09, 4b, 08, 09, 01, 09, 4f, 0a, 08, 00, 10, 05, 00, 11, 04, 06, 5a, 04, 06, 00, 07, 57, 01, 05, 03, 02] +Raw bytes (170): 0x[01, 01, 17, 01, 00, 01, 00, 01, 00, 01, 00, 01, 00, 01, 00, 01, 00, 01, 00, 01, 00, 01, 00, 01, 00, 01, 00, 01, 00, 01, 00, 01, 00, 01, 00, 01, 00, 01, 00, 01, 00, 01, 00, 01, 05, 05, 5a, 01, 05, 18, 01, 08, 01, 0f, 0d, 03, 16, 0e, 06, 0a, 07, 10, 05, 13, 0d, 0b, 1a, 0e, 06, 0a, 0f, 10, 05, 0c, 16, 13, 16, 05, 0d, 18, 17, 19, 09, 01, 1e, 1b, 04, 09, 00, 29, 1f, 01, 09, 00, 2d, 23, 01, 09, 00, 24, 27, 05, 09, 00, 24, 2b, 02, 09, 00, 21, 2f, 04, 09, 00, 21, 33, 04, 09, 00, 28, 37, 09, 09, 00, 32, 3b, 04, 09, 00, 33, 3f, 07, 09, 00, 4b, 43, 08, 09, 00, 48, 47, 0a, 09, 00, 47, 4b, 08, 09, 00, 44, 4f, 0a, 08, 00, 10, 05, 00, 11, 04, 06, 5a, 04, 06, 00, 07, 57, 01, 05, 03, 02] Number of files: 1 - file 0 => global file 1 Number of expressions: 23 @@ -32,13 +32,13 @@ Number of file 0 mappings: 24 = (c0 + Zero) - Code(Expression(1, Add)) at (prev + 16, 5) to (start + 19, 13) = (c0 + Zero) -- Code(Expression(2, Add)) at (prev + 26, 14) to (start + 8, 9) +- Code(Expression(2, Add)) at (prev + 26, 14) to (start + 6, 10) = (c0 + Zero) -- Code(Expression(3, Add)) at (prev + 16, 5) to (start + 14, 9) +- Code(Expression(3, Add)) at (prev + 16, 5) to (start + 12, 22) = (c0 + Zero) - Code(Expression(4, Add)) at (prev + 22, 5) to (start + 13, 24) = (c0 + Zero) -- Code(Expression(5, Add)) at (prev + 25, 9) to (start + 1, 33) +- Code(Expression(5, Add)) at (prev + 25, 9) to (start + 1, 30) = (c0 + Zero) - Code(Expression(6, Add)) at (prev + 4, 9) to (start + 0, 41) = (c0 + Zero) @@ -60,11 +60,11 @@ Number of file 0 mappings: 24 = (c0 + Zero) - Code(Expression(15, Add)) at (prev + 7, 9) to (start + 0, 75) = (c0 + Zero) -- Code(Expression(16, Add)) at (prev + 8, 9) to (start + 1, 9) +- Code(Expression(16, Add)) at (prev + 8, 9) to (start + 0, 72) = (c0 + Zero) -- Code(Expression(17, Add)) at (prev + 10, 9) to (start + 1, 9) +- Code(Expression(17, Add)) at (prev + 10, 9) to (start + 0, 71) = (c0 + Zero) -- Code(Expression(18, Add)) at (prev + 8, 9) to (start + 1, 9) +- Code(Expression(18, Add)) at (prev + 8, 9) to (start + 0, 68) = (c0 + Zero) - Code(Expression(19, Add)) at (prev + 10, 8) to (start + 0, 16) = (c0 + Zero) diff --git a/tests/coverage-map/status-quo/closure_bug.cov-map b/tests/coverage-map/status-quo/closure_bug.cov-map new file mode 100644 index 00000000000..4fe2e5ad243 --- /dev/null +++ b/tests/coverage-map/status-quo/closure_bug.cov-map @@ -0,0 +1,148 @@ +Function name: closure_bug::main +Raw bytes (241): 0x[01, 01, 34, 01, 00, 01, 05, 05, ce, 01, 01, 05, cb, 01, 00, 05, ce, 01, 01, 05, cb, 01, 09, 05, ce, 01, 01, 05, 09, c6, 01, cb, 01, 09, 05, ce, 01, 01, 05, c3, 01, 00, 09, c6, 01, cb, 01, 09, 05, ce, 01, 01, 05, c3, 01, 0d, 09, c6, 01, cb, 01, 09, 05, ce, 01, 01, 05, 0d, be, 01, c3, 01, 0d, 09, c6, 01, cb, 01, 09, 05, ce, 01, 01, 05, bb, 01, 00, 0d, be, 01, c3, 01, 0d, 09, c6, 01, cb, 01, 09, 05, ce, 01, 01, 05, bb, 01, 11, 0d, be, 01, c3, 01, 0d, 09, c6, 01, cb, 01, 09, 05, ce, 01, 01, 05, 11, b6, 01, bb, 01, 11, 0d, be, 01, c3, 01, 0d, 09, c6, 01, cb, 01, 09, 05, ce, 01, 01, 05, 11, 01, 06, 01, 03, 0a, 03, 09, 05, 01, 0e, 05, 01, 0f, 00, 17, ce, 01, 00, 17, 00, 18, cb, 01, 02, 09, 00, 0a, 13, 06, 05, 01, 0e, 09, 01, 0f, 00, 17, c6, 01, 00, 17, 00, 18, c3, 01, 02, 09, 00, 0a, 3b, 06, 05, 01, 0e, 0d, 01, 0f, 00, 17, be, 01, 00, 17, 00, 18, bb, 01, 02, 09, 00, 0a, 7b, 06, 05, 01, 0e, 11, 01, 0f, 00, 17, b6, 01, 00, 17, 00, 18, b3, 01, 01, 01, 00, 02] +Number of files: 1 +- file 0 => global file 1 +Number of expressions: 52 +- expression 0 operands: lhs = Counter(0), rhs = Zero +- expression 1 operands: lhs = Counter(0), rhs = Counter(1) +- expression 2 operands: lhs = Counter(1), rhs = Expression(51, Sub) +- expression 3 operands: lhs = Counter(0), rhs = Counter(1) +- expression 4 operands: lhs = Expression(50, Add), rhs = Zero +- expression 5 operands: lhs = Counter(1), rhs = Expression(51, Sub) +- expression 6 operands: lhs = Counter(0), rhs = Counter(1) +- expression 7 operands: lhs = Expression(50, Add), rhs = Counter(2) +- expression 8 operands: lhs = Counter(1), rhs = Expression(51, Sub) +- expression 9 operands: lhs = Counter(0), rhs = Counter(1) +- expression 10 operands: lhs = Counter(2), rhs = Expression(49, Sub) +- expression 11 operands: lhs = Expression(50, Add), rhs = Counter(2) +- expression 12 operands: lhs = Counter(1), rhs = Expression(51, Sub) +- expression 13 operands: lhs = Counter(0), rhs = Counter(1) +- expression 14 operands: lhs = Expression(48, Add), rhs = Zero +- expression 15 operands: lhs = Counter(2), rhs = Expression(49, Sub) +- expression 16 operands: lhs = Expression(50, Add), rhs = Counter(2) +- expression 17 operands: lhs = Counter(1), rhs = Expression(51, Sub) +- expression 18 operands: lhs = Counter(0), rhs = Counter(1) +- expression 19 operands: lhs = Expression(48, Add), rhs = Counter(3) +- expression 20 operands: lhs = Counter(2), rhs = Expression(49, Sub) +- expression 21 operands: lhs = Expression(50, Add), rhs = Counter(2) +- expression 22 operands: lhs = Counter(1), rhs = Expression(51, Sub) +- expression 23 operands: lhs = Counter(0), rhs = Counter(1) +- expression 24 operands: lhs = Counter(3), rhs = Expression(47, Sub) +- expression 25 operands: lhs = Expression(48, Add), rhs = Counter(3) +- expression 26 operands: lhs = Counter(2), rhs = Expression(49, Sub) +- expression 27 operands: lhs = Expression(50, Add), rhs = Counter(2) +- expression 28 operands: lhs = Counter(1), rhs = Expression(51, Sub) +- expression 29 operands: lhs = Counter(0), rhs = Counter(1) +- expression 30 operands: lhs = Expression(46, Add), rhs = Zero +- expression 31 operands: lhs = Counter(3), rhs = Expression(47, Sub) +- expression 32 operands: lhs = Expression(48, Add), rhs = Counter(3) +- expression 33 operands: lhs = Counter(2), rhs = Expression(49, Sub) +- expression 34 operands: lhs = Expression(50, Add), rhs = Counter(2) +- expression 35 operands: lhs = Counter(1), rhs = Expression(51, Sub) +- expression 36 operands: lhs = Counter(0), rhs = Counter(1) +- expression 37 operands: lhs = Expression(46, Add), rhs = Counter(4) +- expression 38 operands: lhs = Counter(3), rhs = Expression(47, Sub) +- expression 39 operands: lhs = Expression(48, Add), rhs = Counter(3) +- expression 40 operands: lhs = Counter(2), rhs = Expression(49, Sub) +- expression 41 operands: lhs = Expression(50, Add), rhs = Counter(2) +- expression 42 operands: lhs = Counter(1), rhs = Expression(51, Sub) +- expression 43 operands: lhs = Counter(0), rhs = Counter(1) +- expression 44 operands: lhs = Counter(4), rhs = Expression(45, Sub) +- expression 45 operands: lhs = Expression(46, Add), rhs = Counter(4) +- expression 46 operands: lhs = Counter(3), rhs = Expression(47, Sub) +- expression 47 operands: lhs = Expression(48, Add), rhs = Counter(3) +- expression 48 operands: lhs = Counter(2), rhs = Expression(49, Sub) +- expression 49 operands: lhs = Expression(50, Add), rhs = Counter(2) +- expression 50 operands: lhs = Counter(1), rhs = Expression(51, Sub) +- expression 51 operands: lhs = Counter(0), rhs = Counter(1) +Number of file 0 mappings: 17 +- Code(Counter(0)) at (prev + 6, 1) to (start + 3, 10) +- Code(Expression(0, Add)) at (prev + 9, 5) to (start + 1, 14) + = (c0 + Zero) +- Code(Counter(1)) at (prev + 1, 15) to (start + 0, 23) +- Code(Expression(51, Sub)) at (prev + 0, 23) to (start + 0, 24) + = (c0 - c1) +- Code(Expression(50, Add)) at (prev + 2, 9) to (start + 0, 10) + = (c1 + (c0 - c1)) +- Code(Expression(4, Add)) at (prev + 6, 5) to (start + 1, 14) + = ((c1 + (c0 - c1)) + Zero) +- Code(Counter(2)) at (prev + 1, 15) to (start + 0, 23) +- Code(Expression(49, Sub)) at (prev + 0, 23) to (start + 0, 24) + = ((c1 + (c0 - c1)) - c2) +- Code(Expression(48, Add)) at (prev + 2, 9) to (start + 0, 10) + = (c2 + ((c1 + (c0 - c1)) - c2)) +- Code(Expression(14, Add)) at (prev + 6, 5) to (start + 1, 14) + = ((c2 + ((c1 + (c0 - c1)) - c2)) + Zero) +- Code(Counter(3)) at (prev + 1, 15) to (start + 0, 23) +- Code(Expression(47, Sub)) at (prev + 0, 23) to (start + 0, 24) + = ((c2 + ((c1 + (c0 - c1)) - c2)) - c3) +- Code(Expression(46, Add)) at (prev + 2, 9) to (start + 0, 10) + = (c3 + ((c2 + ((c1 + (c0 - c1)) - c2)) - c3)) +- Code(Expression(30, Add)) at (prev + 6, 5) to (start + 1, 14) + = ((c3 + ((c2 + ((c1 + (c0 - c1)) - c2)) - c3)) + Zero) +- Code(Counter(4)) at (prev + 1, 15) to (start + 0, 23) +- Code(Expression(45, Sub)) at (prev + 0, 23) to (start + 0, 24) + = ((c3 + ((c2 + ((c1 + (c0 - c1)) - c2)) - c3)) - c4) +- Code(Expression(44, Add)) at (prev + 1, 1) to (start + 0, 2) + = (c4 + ((c3 + ((c2 + ((c1 + (c0 - c1)) - c2)) - c3)) - c4)) + +Function name: closure_bug::main::{closure#0} +Raw bytes (28): 0x[01, 01, 02, 01, 05, 05, 02, 04, 01, 0d, 09, 00, 12, 05, 00, 15, 00, 19, 02, 00, 23, 00, 28, 07, 00, 29, 00, 2a] +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 + 13, 9) to (start + 0, 18) +- Code(Counter(1)) at (prev + 0, 21) to (start + 0, 25) +- Code(Expression(0, Sub)) at (prev + 0, 35) to (start + 0, 40) + = (c0 - c1) +- Code(Expression(1, Add)) at (prev + 0, 41) to (start + 0, 42) + = (c1 + (c0 - c1)) + +Function name: closure_bug::main::{closure#1} +Raw bytes (28): 0x[01, 01, 02, 01, 05, 05, 02, 04, 01, 16, 09, 00, 12, 05, 00, 15, 00, 19, 02, 00, 23, 00, 28, 07, 00, 29, 00, 2a] +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 + 22, 9) to (start + 0, 18) +- Code(Counter(1)) at (prev + 0, 21) to (start + 0, 25) +- Code(Expression(0, Sub)) at (prev + 0, 35) to (start + 0, 40) + = (c0 - c1) +- Code(Expression(1, Add)) at (prev + 0, 41) to (start + 0, 42) + = (c1 + (c0 - c1)) + +Function name: closure_bug::main::{closure#2} +Raw bytes (28): 0x[01, 01, 02, 01, 05, 05, 02, 04, 01, 1f, 09, 00, 12, 05, 00, 15, 00, 19, 02, 00, 23, 00, 28, 07, 00, 29, 00, 2a] +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 + 31, 9) to (start + 0, 18) +- Code(Counter(1)) at (prev + 0, 21) to (start + 0, 25) +- Code(Expression(0, Sub)) at (prev + 0, 35) to (start + 0, 40) + = (c0 - c1) +- Code(Expression(1, Add)) at (prev + 0, 41) to (start + 0, 42) + = (c1 + (c0 - c1)) + +Function name: closure_bug::main::{closure#3} +Raw bytes (28): 0x[01, 01, 02, 01, 05, 05, 02, 04, 01, 28, 09, 00, 12, 05, 00, 15, 00, 19, 02, 00, 23, 00, 28, 07, 00, 29, 00, 2a] +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 + 40, 9) to (start + 0, 18) +- Code(Counter(1)) at (prev + 0, 21) to (start + 0, 25) +- Code(Expression(0, Sub)) at (prev + 0, 35) to (start + 0, 40) + = (c0 - c1) +- Code(Expression(1, Add)) at (prev + 0, 41) to (start + 0, 42) + = (c1 + (c0 - c1)) + diff --git a/tests/coverage-map/status-quo/closure_bug.rs b/tests/coverage-map/status-quo/closure_bug.rs new file mode 100644 index 00000000000..739bc5f0b51 --- /dev/null +++ b/tests/coverage-map/status-quo/closure_bug.rs @@ -0,0 +1,44 @@ +// Regression test for #115930. +// All of these closures are identical, and should produce identical output in +// the coverage report. However, an unstable sort was causing them to be treated +// inconsistently when preparing coverage spans. + +fn main() { + let truthy = std::env::args().len() == 1; + + let a + = + | + | + if truthy { true } else { false }; + + a(); + if truthy { a(); } + + let b + = + | + | + if truthy { true } else { false }; + + b(); + if truthy { b(); } + + let c + = + | + | + if truthy { true } else { false }; + + c(); + if truthy { c(); } + + let d + = + | + | + if truthy { true } else { false }; + + d(); + if truthy { d(); } +} diff --git a/tests/coverage-map/status-quo/closure_macro.rs b/tests/coverage-map/status-quo/closure_macro.rs index 5e3b00d1ef5..9b289141c2e 100644 --- a/tests/coverage-map/status-quo/closure_macro.rs +++ b/tests/coverage-map/status-quo/closure_macro.rs @@ -1,5 +1,5 @@ // compile-flags: --edition=2018 -#![feature(no_coverage)] +#![feature(coverage_attribute)] macro_rules! bail { ($msg:literal $(,)?) => { diff --git a/tests/coverage-map/status-quo/closure_macro_async.rs b/tests/coverage-map/status-quo/closure_macro_async.rs index 3d6bdb38a2a..b4275599e59 100644 --- a/tests/coverage-map/status-quo/closure_macro_async.rs +++ b/tests/coverage-map/status-quo/closure_macro_async.rs @@ -1,5 +1,5 @@ // compile-flags: --edition=2018 -#![feature(no_coverage)] +#![feature(coverage_attribute)] macro_rules! bail { ($msg:literal $(,)?) => { @@ -39,7 +39,7 @@ pub async fn test() -> Result<(), String> { Ok(()) } -#[no_coverage] +#[coverage(off)] fn main() { executor::block_on(test()).unwrap(); } @@ -51,18 +51,18 @@ mod executor { task::{Context, Poll, RawWaker, RawWakerVTable, Waker}, }; - #[no_coverage] + #[coverage(off)] pub fn block_on<F: Future>(mut future: F) -> F::Output { let mut future = unsafe { Pin::new_unchecked(&mut future) }; use std::hint::unreachable_unchecked; static VTABLE: RawWakerVTable = RawWakerVTable::new( - #[no_coverage] + #[coverage(off)] |_| unsafe { unreachable_unchecked() }, // clone - #[no_coverage] + #[coverage(off)] |_| unsafe { unreachable_unchecked() }, // wake - #[no_coverage] + #[coverage(off)] |_| unsafe { unreachable_unchecked() }, // wake_by_ref - #[no_coverage] + #[coverage(off)] |_| (), ); let waker = unsafe { Waker::from_raw(RawWaker::new(core::ptr::null(), &VTABLE)) }; diff --git a/tests/coverage-map/status-quo/generator.cov-map b/tests/coverage-map/status-quo/generator.cov-map index 6e10b58a941..a66c1af30f9 100644 --- a/tests/coverage-map/status-quo/generator.cov-map +++ b/tests/coverage-map/status-quo/generator.cov-map @@ -14,7 +14,7 @@ Number of file 0 mappings: 4 = (c1 + (c0 - c1)) Function name: generator::main -Raw bytes (71): 0x[01, 01, 0b, 01, 00, 05, 0b, 09, 0d, 11, 00, 11, 15, 2a, 19, 11, 15, 15, 19, 26, 00, 2a, 19, 11, 15, 09, 01, 0f, 01, 02, 19, 03, 07, 0b, 00, 2e, 11, 01, 2b, 00, 2d, 07, 01, 0e, 00, 35, 0f, 02, 0b, 00, 2e, 2a, 01, 22, 00, 27, 26, 00, 2c, 00, 2e, 1f, 01, 0e, 00, 35, 23, 02, 01, 00, 02] +Raw bytes (71): 0x[01, 01, 0b, 01, 00, 05, 0b, 09, 0d, 11, 00, 11, 15, 2a, 19, 11, 15, 15, 19, 26, 00, 2a, 19, 11, 15, 09, 01, 0f, 01, 02, 16, 03, 07, 0b, 00, 2e, 11, 01, 2b, 00, 2d, 07, 01, 0e, 00, 35, 0f, 02, 0b, 00, 2e, 2a, 01, 22, 00, 27, 26, 00, 2c, 00, 2e, 1f, 01, 0e, 00, 35, 23, 02, 01, 00, 02] Number of files: 1 - file 0 => global file 1 Number of expressions: 11 @@ -30,7 +30,7 @@ Number of expressions: 11 - expression 9 operands: lhs = Expression(10, Sub), rhs = Counter(6) - expression 10 operands: lhs = Counter(4), rhs = Counter(5) Number of file 0 mappings: 9 -- Code(Counter(0)) at (prev + 15, 1) to (start + 2, 25) +- Code(Counter(0)) at (prev + 15, 1) to (start + 2, 22) - Code(Expression(0, Add)) at (prev + 7, 11) to (start + 0, 46) = (c0 + Zero) - Code(Counter(4)) at (prev + 1, 43) to (start + 0, 45) diff --git a/tests/coverage-map/status-quo/no_cov_crate.rs b/tests/coverage-map/status-quo/no_cov_crate.rs index 5b748aeefb7..e12e4bc55e3 100644 --- a/tests/coverage-map/status-quo/no_cov_crate.rs +++ b/tests/coverage-map/status-quo/no_cov_crate.rs @@ -1,17 +1,17 @@ -// Enables `no_coverage` on the entire crate -#![feature(no_coverage)] +// Enables `coverage(off)` on the entire crate +#![feature(coverage_attribute)] -#[no_coverage] +#[coverage(off)] fn do_not_add_coverage_1() { println!("called but not covered"); } fn do_not_add_coverage_2() { - #![no_coverage] + #![coverage(off)] println!("called but not covered"); } -#[no_coverage] +#[coverage(off)] #[allow(dead_code)] fn do_not_add_coverage_not_called() { println!("not called and not covered"); @@ -33,7 +33,7 @@ fn add_coverage_not_called() { // FIXME: These test-cases illustrate confusing results of nested functions. // See https://github.com/rust-lang/rust/issues/93319 mod nested_fns { - #[no_coverage] + #[coverage(off)] pub fn outer_not_covered(is_true: bool) { fn inner(is_true: bool) { if is_true { @@ -50,7 +50,7 @@ mod nested_fns { println!("called and covered"); inner_not_covered(is_true); - #[no_coverage] + #[coverage(off)] fn inner_not_covered(is_true: bool) { if is_true { println!("called but not covered"); diff --git a/tests/debuginfo/pretty-std-collections.rs b/tests/debuginfo/pretty-std-collections.rs index 93597aa7e23..93a0dff6848 100644 --- a/tests/debuginfo/pretty-std-collections.rs +++ b/tests/debuginfo/pretty-std-collections.rs @@ -1,7 +1,6 @@ // ignore-windows failing on win32 bot // ignore-freebsd: gdb package too new // ignore-android: FIXME(#10381) -// ignore-macos: FIXME(#78665) // compile-flags:-g // The pretty printers being tested here require the patch from diff --git a/tests/mir-opt/const_prop/checked_add.main.ConstProp.panic-abort.diff b/tests/mir-opt/const_prop/checked_add.main.ConstProp.panic-abort.diff index 6daef87dd2c..c2fd7f65f5e 100644 --- a/tests/mir-opt/const_prop/checked_add.main.ConstProp.panic-abort.diff +++ b/tests/mir-opt/const_prop/checked_add.main.ConstProp.panic-abort.diff @@ -24,5 +24,9 @@ StorageDead(_1); return; } ++ } ++ ++ alloc3 (size: 8, align: 4) { ++ 02 00 00 00 00 __ __ __ │ .....░░░ } diff --git a/tests/mir-opt/const_prop/checked_add.main.ConstProp.panic-unwind.diff b/tests/mir-opt/const_prop/checked_add.main.ConstProp.panic-unwind.diff index 125407bf285..21a31f9aba3 100644 --- a/tests/mir-opt/const_prop/checked_add.main.ConstProp.panic-unwind.diff +++ b/tests/mir-opt/const_prop/checked_add.main.ConstProp.panic-unwind.diff @@ -24,5 +24,9 @@ StorageDead(_1); return; } ++ } ++ ++ alloc3 (size: 8, align: 4) { ++ 02 00 00 00 00 __ __ __ │ .....░░░ } diff --git a/tests/mir-opt/const_prop/indirect.main.ConstProp.panic-abort.diff b/tests/mir-opt/const_prop/indirect.main.ConstProp.panic-abort.diff index ca0ce2888cd..c0efc873029 100644 --- a/tests/mir-opt/const_prop/indirect.main.ConstProp.panic-abort.diff +++ b/tests/mir-opt/const_prop/indirect.main.ConstProp.panic-abort.diff @@ -29,5 +29,9 @@ StorageDead(_1); return; } ++ } ++ ++ alloc3 (size: 2, align: 1) { ++ 03 00 │ .. } diff --git a/tests/mir-opt/const_prop/indirect.main.ConstProp.panic-unwind.diff b/tests/mir-opt/const_prop/indirect.main.ConstProp.panic-unwind.diff index d63fb9255a3..2aee6f164ae 100644 --- a/tests/mir-opt/const_prop/indirect.main.ConstProp.panic-unwind.diff +++ b/tests/mir-opt/const_prop/indirect.main.ConstProp.panic-unwind.diff @@ -29,5 +29,9 @@ StorageDead(_1); return; } ++ } ++ ++ alloc3 (size: 2, align: 1) { ++ 03 00 │ .. } diff --git a/tests/mir-opt/const_prop/inherit_overflow.main.ConstProp.panic-abort.diff b/tests/mir-opt/const_prop/inherit_overflow.main.ConstProp.panic-abort.diff index 51e17cf690a..7ba51ccdbf6 100644 --- a/tests/mir-opt/const_prop/inherit_overflow.main.ConstProp.panic-abort.diff +++ b/tests/mir-opt/const_prop/inherit_overflow.main.ConstProp.panic-abort.diff @@ -35,5 +35,9 @@ _0 = const (); return; } ++ } ++ ++ alloc3 (size: 2, align: 1) { ++ 00 01 │ .. } diff --git a/tests/mir-opt/const_prop/inherit_overflow.main.ConstProp.panic-unwind.diff b/tests/mir-opt/const_prop/inherit_overflow.main.ConstProp.panic-unwind.diff index 5ef201497fb..545b7f22f6e 100644 --- a/tests/mir-opt/const_prop/inherit_overflow.main.ConstProp.panic-unwind.diff +++ b/tests/mir-opt/const_prop/inherit_overflow.main.ConstProp.panic-unwind.diff @@ -35,5 +35,9 @@ _0 = const (); return; } ++ } ++ ++ alloc3 (size: 2, align: 1) { ++ 00 01 │ .. } diff --git a/tests/mir-opt/const_prop/issue_66971.main.ConstProp.panic-abort.diff b/tests/mir-opt/const_prop/issue_66971.main.ConstProp.panic-abort.diff index 170c019782d..18341ba7db9 100644 --- a/tests/mir-opt/const_prop/issue_66971.main.ConstProp.panic-abort.diff +++ b/tests/mir-opt/const_prop/issue_66971.main.ConstProp.panic-abort.diff @@ -18,5 +18,13 @@ StorageDead(_2); return; } ++ } ++ ++ alloc8 (size: 2, align: 1) { ++ 00 00 │ .. ++ } ++ ++ alloc7 (size: 2, align: 1) { ++ 00 00 │ .. } diff --git a/tests/mir-opt/const_prop/issue_66971.main.ConstProp.panic-unwind.diff b/tests/mir-opt/const_prop/issue_66971.main.ConstProp.panic-unwind.diff index 64227dfd78c..50763c10f0c 100644 --- a/tests/mir-opt/const_prop/issue_66971.main.ConstProp.panic-unwind.diff +++ b/tests/mir-opt/const_prop/issue_66971.main.ConstProp.panic-unwind.diff @@ -18,5 +18,13 @@ StorageDead(_2); return; } ++ } ++ ++ alloc8 (size: 2, align: 1) { ++ 00 00 │ .. ++ } ++ ++ alloc7 (size: 2, align: 1) { ++ 00 00 │ .. } diff --git a/tests/mir-opt/const_prop/issue_67019.main.ConstProp.panic-abort.diff b/tests/mir-opt/const_prop/issue_67019.main.ConstProp.panic-abort.diff index e1f3f37b370..015180db896 100644 --- a/tests/mir-opt/const_prop/issue_67019.main.ConstProp.panic-abort.diff +++ b/tests/mir-opt/const_prop/issue_67019.main.ConstProp.panic-abort.diff @@ -23,5 +23,17 @@ StorageDead(_2); return; } ++ } ++ ++ alloc12 (size: 2, align: 1) { ++ 01 02 │ .. ++ } ++ ++ alloc11 (size: 2, align: 1) { ++ 01 02 │ .. ++ } ++ ++ alloc8 (size: 2, align: 1) { ++ 01 02 │ .. } diff --git a/tests/mir-opt/const_prop/issue_67019.main.ConstProp.panic-unwind.diff b/tests/mir-opt/const_prop/issue_67019.main.ConstProp.panic-unwind.diff index aaa376a95cf..8e41705c1af 100644 --- a/tests/mir-opt/const_prop/issue_67019.main.ConstProp.panic-unwind.diff +++ b/tests/mir-opt/const_prop/issue_67019.main.ConstProp.panic-unwind.diff @@ -23,5 +23,17 @@ StorageDead(_2); return; } ++ } ++ ++ alloc12 (size: 2, align: 1) { ++ 01 02 │ .. ++ } ++ ++ alloc11 (size: 2, align: 1) { ++ 01 02 │ .. ++ } ++ ++ alloc8 (size: 2, align: 1) { ++ 01 02 │ .. } diff --git a/tests/mir-opt/const_prop/mutable_variable_aggregate.main.ConstProp.diff b/tests/mir-opt/const_prop/mutable_variable_aggregate.main.ConstProp.diff index 0f118c7f59f..56a127ae31e 100644 --- a/tests/mir-opt/const_prop/mutable_variable_aggregate.main.ConstProp.diff +++ b/tests/mir-opt/const_prop/mutable_variable_aggregate.main.ConstProp.diff @@ -25,5 +25,13 @@ StorageDead(_1); return; } ++ } ++ ++ alloc7 (size: 8, align: 4) { ++ 2a 00 00 00 63 00 00 00 │ *...c... ++ } ++ ++ alloc5 (size: 8, align: 4) { ++ 2a 00 00 00 2b 00 00 00 │ *...+... } diff --git a/tests/mir-opt/const_prop/mutable_variable_unprop_assign.main.ConstProp.panic-abort.diff b/tests/mir-opt/const_prop/mutable_variable_unprop_assign.main.ConstProp.panic-abort.diff index a85dcf9c7ed..a1b433716c8 100644 --- a/tests/mir-opt/const_prop/mutable_variable_unprop_assign.main.ConstProp.panic-abort.diff +++ b/tests/mir-opt/const_prop/mutable_variable_unprop_assign.main.ConstProp.panic-abort.diff @@ -46,5 +46,9 @@ StorageDead(_1); return; } ++ } ++ ++ alloc7 (size: 8, align: 4) { ++ 01 00 00 00 02 00 00 00 │ ........ } diff --git a/tests/mir-opt/const_prop/mutable_variable_unprop_assign.main.ConstProp.panic-unwind.diff b/tests/mir-opt/const_prop/mutable_variable_unprop_assign.main.ConstProp.panic-unwind.diff index 15ef0fa4dff..2dc514194bc 100644 --- a/tests/mir-opt/const_prop/mutable_variable_unprop_assign.main.ConstProp.panic-unwind.diff +++ b/tests/mir-opt/const_prop/mutable_variable_unprop_assign.main.ConstProp.panic-unwind.diff @@ -46,5 +46,9 @@ StorageDead(_1); return; } ++ } ++ ++ alloc7 (size: 8, align: 4) { ++ 01 00 00 00 02 00 00 00 │ ........ } diff --git a/tests/mir-opt/const_prop/return_place.add.ConstProp.panic-abort.diff b/tests/mir-opt/const_prop/return_place.add.ConstProp.panic-abort.diff index f3b30e0dcde..6c9de476465 100644 --- a/tests/mir-opt/const_prop/return_place.add.ConstProp.panic-abort.diff +++ b/tests/mir-opt/const_prop/return_place.add.ConstProp.panic-abort.diff @@ -17,5 +17,9 @@ + _0 = const 4_u32; return; } ++ } ++ ++ alloc5 (size: 8, align: 4) { ++ 04 00 00 00 00 __ __ __ │ .....░░░ } diff --git a/tests/mir-opt/const_prop/return_place.add.ConstProp.panic-unwind.diff b/tests/mir-opt/const_prop/return_place.add.ConstProp.panic-unwind.diff index 79f85fcef11..0f079278c43 100644 --- a/tests/mir-opt/const_prop/return_place.add.ConstProp.panic-unwind.diff +++ b/tests/mir-opt/const_prop/return_place.add.ConstProp.panic-unwind.diff @@ -17,5 +17,9 @@ + _0 = const 4_u32; return; } ++ } ++ ++ alloc5 (size: 8, align: 4) { ++ 04 00 00 00 00 __ __ __ │ .....░░░ } diff --git a/tests/mir-opt/const_prop/return_place.add.PreCodegen.before.panic-abort.mir b/tests/mir-opt/const_prop/return_place.add.PreCodegen.before.panic-abort.mir index c8f3f641a6d..c2488f3944c 100644 --- a/tests/mir-opt/const_prop/return_place.add.PreCodegen.before.panic-abort.mir +++ b/tests/mir-opt/const_prop/return_place.add.PreCodegen.before.panic-abort.mir @@ -14,3 +14,7 @@ fn add() -> u32 { return; } } + +alloc5 (size: 8, align: 4) { + 04 00 00 00 00 __ __ __ │ .....░░░ +} diff --git a/tests/mir-opt/const_prop/return_place.add.PreCodegen.before.panic-unwind.mir b/tests/mir-opt/const_prop/return_place.add.PreCodegen.before.panic-unwind.mir index 9a064697463..fa0b9c77eaf 100644 --- a/tests/mir-opt/const_prop/return_place.add.PreCodegen.before.panic-unwind.mir +++ b/tests/mir-opt/const_prop/return_place.add.PreCodegen.before.panic-unwind.mir @@ -14,3 +14,7 @@ fn add() -> u32 { return; } } + +alloc5 (size: 8, align: 4) { + 04 00 00 00 00 __ __ __ │ .....░░░ +} diff --git a/tests/mir-opt/const_prop/tuple_literal_propagation.main.ConstProp.panic-abort.diff b/tests/mir-opt/const_prop/tuple_literal_propagation.main.ConstProp.panic-abort.diff index 9e705695ac0..988ef7dd225 100644 --- a/tests/mir-opt/const_prop/tuple_literal_propagation.main.ConstProp.panic-abort.diff +++ b/tests/mir-opt/const_prop/tuple_literal_propagation.main.ConstProp.panic-abort.diff @@ -29,5 +29,17 @@ StorageDead(_1); return; } ++ } ++ ++ alloc9 (size: 8, align: 4) { ++ 01 00 00 00 02 00 00 00 │ ........ ++ } ++ ++ alloc8 (size: 8, align: 4) { ++ 01 00 00 00 02 00 00 00 │ ........ ++ } ++ ++ alloc6 (size: 8, align: 4) { ++ 01 00 00 00 02 00 00 00 │ ........ } diff --git a/tests/mir-opt/const_prop/tuple_literal_propagation.main.ConstProp.panic-unwind.diff b/tests/mir-opt/const_prop/tuple_literal_propagation.main.ConstProp.panic-unwind.diff index 882dd97cc16..29844619720 100644 --- a/tests/mir-opt/const_prop/tuple_literal_propagation.main.ConstProp.panic-unwind.diff +++ b/tests/mir-opt/const_prop/tuple_literal_propagation.main.ConstProp.panic-unwind.diff @@ -29,5 +29,17 @@ StorageDead(_1); return; } ++ } ++ ++ alloc9 (size: 8, align: 4) { ++ 01 00 00 00 02 00 00 00 │ ........ ++ } ++ ++ alloc8 (size: 8, align: 4) { ++ 01 00 00 00 02 00 00 00 │ ........ ++ } ++ ++ alloc6 (size: 8, align: 4) { ++ 01 00 00 00 02 00 00 00 │ ........ } diff --git a/tests/mir-opt/dataflow-const-prop/enum.constant.DataflowConstProp.32bit.diff b/tests/mir-opt/dataflow-const-prop/enum.constant.DataflowConstProp.32bit.diff new file mode 100644 index 00000000000..07ac5b72e24 --- /dev/null +++ b/tests/mir-opt/dataflow-const-prop/enum.constant.DataflowConstProp.32bit.diff @@ -0,0 +1,63 @@ +- // MIR for `constant` before DataflowConstProp ++ // MIR for `constant` after DataflowConstProp + + fn constant() -> () { + let mut _0: (); + let _1: E; + let mut _3: isize; + scope 1 { + debug e => _1; + let _2: i32; + let _4: i32; + let _5: i32; + scope 2 { + debug x => _2; + } + scope 3 { + debug x => _4; + } + scope 4 { + debug x => _5; + } + } + + bb0: { + StorageLive(_1); + _1 = const _; + StorageLive(_2); +- _3 = discriminant(_1); +- switchInt(move _3) -> [0: bb3, 1: bb1, otherwise: bb2]; ++ _3 = const 0_isize; ++ switchInt(const 0_isize) -> [0: bb3, 1: bb1, otherwise: bb2]; + } + + bb1: { + StorageLive(_5); + _5 = ((_1 as V2).0: i32); + _2 = _5; + StorageDead(_5); + goto -> bb4; + } + + bb2: { + unreachable; + } + + bb3: { + StorageLive(_4); +- _4 = ((_1 as V1).0: i32); +- _2 = _4; ++ _4 = const 0_i32; ++ _2 = const 0_i32; + StorageDead(_4); + goto -> bb4; + } + + bb4: { + _0 = const (); + StorageDead(_2); + StorageDead(_1); + return; + } + } + diff --git a/tests/mir-opt/dataflow-const-prop/enum.constant.DataflowConstProp.64bit.diff b/tests/mir-opt/dataflow-const-prop/enum.constant.DataflowConstProp.64bit.diff new file mode 100644 index 00000000000..07ac5b72e24 --- /dev/null +++ b/tests/mir-opt/dataflow-const-prop/enum.constant.DataflowConstProp.64bit.diff @@ -0,0 +1,63 @@ +- // MIR for `constant` before DataflowConstProp ++ // MIR for `constant` after DataflowConstProp + + fn constant() -> () { + let mut _0: (); + let _1: E; + let mut _3: isize; + scope 1 { + debug e => _1; + let _2: i32; + let _4: i32; + let _5: i32; + scope 2 { + debug x => _2; + } + scope 3 { + debug x => _4; + } + scope 4 { + debug x => _5; + } + } + + bb0: { + StorageLive(_1); + _1 = const _; + StorageLive(_2); +- _3 = discriminant(_1); +- switchInt(move _3) -> [0: bb3, 1: bb1, otherwise: bb2]; ++ _3 = const 0_isize; ++ switchInt(const 0_isize) -> [0: bb3, 1: bb1, otherwise: bb2]; + } + + bb1: { + StorageLive(_5); + _5 = ((_1 as V2).0: i32); + _2 = _5; + StorageDead(_5); + goto -> bb4; + } + + bb2: { + unreachable; + } + + bb3: { + StorageLive(_4); +- _4 = ((_1 as V1).0: i32); +- _2 = _4; ++ _4 = const 0_i32; ++ _2 = const 0_i32; + StorageDead(_4); + goto -> bb4; + } + + bb4: { + _0 = const (); + StorageDead(_2); + StorageDead(_1); + return; + } + } + diff --git a/tests/mir-opt/dataflow-const-prop/enum.multiple.DataflowConstProp.diff b/tests/mir-opt/dataflow-const-prop/enum.multiple.DataflowConstProp.32bit.diff index 775325c4d06..775325c4d06 100644 --- a/tests/mir-opt/dataflow-const-prop/enum.multiple.DataflowConstProp.diff +++ b/tests/mir-opt/dataflow-const-prop/enum.multiple.DataflowConstProp.32bit.diff diff --git a/tests/mir-opt/dataflow-const-prop/enum.multiple.DataflowConstProp.64bit.diff b/tests/mir-opt/dataflow-const-prop/enum.multiple.DataflowConstProp.64bit.diff new file mode 100644 index 00000000000..775325c4d06 --- /dev/null +++ b/tests/mir-opt/dataflow-const-prop/enum.multiple.DataflowConstProp.64bit.diff @@ -0,0 +1,82 @@ +- // MIR for `multiple` before DataflowConstProp ++ // MIR for `multiple` after DataflowConstProp + + fn multiple(_1: bool, _2: u8) -> () { + debug x => _1; + debug i => _2; + let mut _0: (); + let _3: std::option::Option<u8>; + let mut _4: bool; + let mut _5: u8; + let mut _7: isize; + scope 1 { + debug e => _3; + let _6: u8; + let _8: u8; + scope 2 { + debug x => _6; + let _9: u8; + scope 4 { + debug y => _9; + } + } + scope 3 { + debug i => _8; + } + } + + bb0: { + StorageLive(_3); + StorageLive(_4); + _4 = _1; + switchInt(move _4) -> [0: bb2, otherwise: bb1]; + } + + bb1: { + StorageLive(_5); + _5 = _2; + _3 = Option::<u8>::Some(move _5); + StorageDead(_5); + goto -> bb3; + } + + bb2: { + _3 = Option::<u8>::None; + goto -> bb3; + } + + bb3: { + StorageDead(_4); + StorageLive(_6); + _7 = discriminant(_3); + switchInt(move _7) -> [0: bb4, 1: bb6, otherwise: bb5]; + } + + bb4: { + _6 = const 0_u8; + goto -> bb7; + } + + bb5: { + unreachable; + } + + bb6: { + StorageLive(_8); + _8 = ((_3 as Some).0: u8); + _6 = _8; + StorageDead(_8); + goto -> bb7; + } + + bb7: { + StorageLive(_9); + _9 = _6; + _0 = const (); + StorageDead(_9); + StorageDead(_6); + StorageDead(_3); + return; + } + } + diff --git a/tests/mir-opt/dataflow-const-prop/enum.mutate_discriminant.DataflowConstProp.diff b/tests/mir-opt/dataflow-const-prop/enum.mutate_discriminant.DataflowConstProp.32bit.diff index 960e69ee916..960e69ee916 100644 --- a/tests/mir-opt/dataflow-const-prop/enum.mutate_discriminant.DataflowConstProp.diff +++ b/tests/mir-opt/dataflow-const-prop/enum.mutate_discriminant.DataflowConstProp.32bit.diff diff --git a/tests/mir-opt/dataflow-const-prop/enum.mutate_discriminant.DataflowConstProp.64bit.diff b/tests/mir-opt/dataflow-const-prop/enum.mutate_discriminant.DataflowConstProp.64bit.diff new file mode 100644 index 00000000000..960e69ee916 --- /dev/null +++ b/tests/mir-opt/dataflow-const-prop/enum.mutate_discriminant.DataflowConstProp.64bit.diff @@ -0,0 +1,26 @@ +- // MIR for `mutate_discriminant` before DataflowConstProp ++ // MIR for `mutate_discriminant` after DataflowConstProp + + fn mutate_discriminant() -> u8 { + let mut _0: u8; + let mut _1: std::option::Option<NonZeroUsize>; + let mut _2: isize; + + bb0: { + discriminant(_1) = 1; + (((_1 as variant#1).0: NonZeroUsize).0: usize) = const 0_usize; + _2 = discriminant(_1); + switchInt(_2) -> [0: bb1, otherwise: bb2]; + } + + bb1: { + _0 = const 1_u8; + return; + } + + bb2: { + _0 = const 2_u8; + unreachable; + } + } + diff --git a/tests/mir-opt/dataflow-const-prop/enum.rs b/tests/mir-opt/dataflow-const-prop/enum.rs index 79a20d7ef45..5a10e9e883d 100644 --- a/tests/mir-opt/dataflow-const-prop/enum.rs +++ b/tests/mir-opt/dataflow-const-prop/enum.rs @@ -1,9 +1,11 @@ // unit-test: DataflowConstProp +// EMIT_MIR_FOR_EACH_BIT_WIDTH #![feature(custom_mir, core_intrinsics, rustc_attrs)] use std::intrinsics::mir::*; +#[derive(Copy, Clone)] enum E { V1(i32), V2(i32) @@ -15,6 +17,24 @@ fn simple() { let x = match e { E::V1(x) => x, E::V2(x) => x }; } +// EMIT_MIR enum.constant.DataflowConstProp.diff +fn constant() { + const C: E = E::V1(0); + let e = C; + let x = match e { E::V1(x) => x, E::V2(x) => x }; +} + +// EMIT_MIR enum.statics.DataflowConstProp.diff +fn statics() { + static C: E = E::V1(0); + let e = C; + let x = match e { E::V1(x) => x, E::V2(x) => x }; + + static RC: &E = &E::V2(4); + let e = RC; + let x = match e { E::V1(x) => x, E::V2(x) => x }; +} + #[rustc_layout_scalar_valid_range_start(1)] #[rustc_nonnull_optimization_guaranteed] struct NonZeroUsize(usize); @@ -63,6 +83,8 @@ fn multiple(x: bool, i: u8) { fn main() { simple(); + constant(); + statics(); mutate_discriminant(); multiple(false, 5); } diff --git a/tests/mir-opt/dataflow-const-prop/enum.simple.DataflowConstProp.diff b/tests/mir-opt/dataflow-const-prop/enum.simple.DataflowConstProp.32bit.diff index 3946e7c7d96..3946e7c7d96 100644 --- a/tests/mir-opt/dataflow-const-prop/enum.simple.DataflowConstProp.diff +++ b/tests/mir-opt/dataflow-const-prop/enum.simple.DataflowConstProp.32bit.diff diff --git a/tests/mir-opt/dataflow-const-prop/enum.simple.DataflowConstProp.64bit.diff b/tests/mir-opt/dataflow-const-prop/enum.simple.DataflowConstProp.64bit.diff new file mode 100644 index 00000000000..3946e7c7d96 --- /dev/null +++ b/tests/mir-opt/dataflow-const-prop/enum.simple.DataflowConstProp.64bit.diff @@ -0,0 +1,63 @@ +- // MIR for `simple` before DataflowConstProp ++ // MIR for `simple` after DataflowConstProp + + fn simple() -> () { + let mut _0: (); + let _1: E; + let mut _3: isize; + scope 1 { + debug e => _1; + let _2: i32; + let _4: i32; + let _5: i32; + scope 2 { + debug x => _2; + } + scope 3 { + debug x => _4; + } + scope 4 { + debug x => _5; + } + } + + bb0: { + StorageLive(_1); + _1 = E::V1(const 0_i32); + StorageLive(_2); +- _3 = discriminant(_1); +- switchInt(move _3) -> [0: bb3, 1: bb1, otherwise: bb2]; ++ _3 = const 0_isize; ++ switchInt(const 0_isize) -> [0: bb3, 1: bb1, otherwise: bb2]; + } + + bb1: { + StorageLive(_5); + _5 = ((_1 as V2).0: i32); + _2 = _5; + StorageDead(_5); + goto -> bb4; + } + + bb2: { + unreachable; + } + + bb3: { + StorageLive(_4); +- _4 = ((_1 as V1).0: i32); +- _2 = _4; ++ _4 = const 0_i32; ++ _2 = const 0_i32; + StorageDead(_4); + goto -> bb4; + } + + bb4: { + _0 = const (); + StorageDead(_2); + StorageDead(_1); + return; + } + } + diff --git a/tests/mir-opt/dataflow-const-prop/enum.statics.DataflowConstProp.32bit.diff b/tests/mir-opt/dataflow-const-prop/enum.statics.DataflowConstProp.32bit.diff new file mode 100644 index 00000000000..ae8b44c953e --- /dev/null +++ b/tests/mir-opt/dataflow-const-prop/enum.statics.DataflowConstProp.32bit.diff @@ -0,0 +1,126 @@ +- // MIR for `statics` before DataflowConstProp ++ // MIR for `statics` after DataflowConstProp + + fn statics() -> () { + let mut _0: (); + let _1: E; + let mut _2: &E; + let mut _4: isize; + let mut _8: &&E; + let mut _10: isize; + scope 1 { + debug e => _1; + let _3: i32; + let _5: i32; + let _6: i32; + scope 2 { + debug x => _3; + let _7: &E; + scope 5 { + debug e => _7; + let _9: &i32; + let _11: &i32; + let _12: &i32; + scope 6 { + debug x => _9; + } + scope 7 { + debug x => _11; + } + scope 8 { + debug x => _12; + } + } + } + scope 3 { + debug x => _5; + } + scope 4 { + debug x => _6; + } + } + + bb0: { + StorageLive(_1); + StorageLive(_2); + _2 = const {alloc1: &E}; + _1 = (*_2); + StorageDead(_2); + StorageLive(_3); +- _4 = discriminant(_1); +- switchInt(move _4) -> [0: bb3, 1: bb1, otherwise: bb2]; ++ _4 = const 0_isize; ++ switchInt(const 0_isize) -> [0: bb3, 1: bb1, otherwise: bb2]; + } + + bb1: { + StorageLive(_6); + _6 = ((_1 as V2).0: i32); + _3 = _6; + StorageDead(_6); + goto -> bb4; + } + + bb2: { + unreachable; + } + + bb3: { + StorageLive(_5); +- _5 = ((_1 as V1).0: i32); +- _3 = _5; ++ _5 = const 0_i32; ++ _3 = const 0_i32; + StorageDead(_5); + goto -> bb4; + } + + bb4: { + StorageLive(_7); + StorageLive(_8); + _8 = const {alloc2: &&E}; + _7 = (*_8); + StorageDead(_8); + StorageLive(_9); + _10 = discriminant((*_7)); + switchInt(move _10) -> [0: bb6, 1: bb5, otherwise: bb2]; + } + + bb5: { + StorageLive(_12); + _12 = &(((*_7) as V2).0: i32); + _9 = &(*_12); + StorageDead(_12); + goto -> bb7; + } + + bb6: { + StorageLive(_11); + _11 = &(((*_7) as V1).0: i32); + _9 = _11; + StorageDead(_11); + goto -> bb7; + } + + bb7: { + _0 = const (); + StorageDead(_9); + StorageDead(_7); + StorageDead(_3); + StorageDead(_1); + return; + } + } + + alloc2 (static: RC, size: 4, align: 4) { + ╾─alloc14─╼ │ ╾──╼ + } + + alloc14 (size: 8, align: 4) { + 01 00 00 00 04 00 00 00 │ ........ + } + + alloc1 (static: statics::C, size: 8, align: 4) { + 00 00 00 00 00 00 00 00 │ ........ + } + diff --git a/tests/mir-opt/dataflow-const-prop/enum.statics.DataflowConstProp.64bit.diff b/tests/mir-opt/dataflow-const-prop/enum.statics.DataflowConstProp.64bit.diff new file mode 100644 index 00000000000..63799b3bac3 --- /dev/null +++ b/tests/mir-opt/dataflow-const-prop/enum.statics.DataflowConstProp.64bit.diff @@ -0,0 +1,126 @@ +- // MIR for `statics` before DataflowConstProp ++ // MIR for `statics` after DataflowConstProp + + fn statics() -> () { + let mut _0: (); + let _1: E; + let mut _2: &E; + let mut _4: isize; + let mut _8: &&E; + let mut _10: isize; + scope 1 { + debug e => _1; + let _3: i32; + let _5: i32; + let _6: i32; + scope 2 { + debug x => _3; + let _7: &E; + scope 5 { + debug e => _7; + let _9: &i32; + let _11: &i32; + let _12: &i32; + scope 6 { + debug x => _9; + } + scope 7 { + debug x => _11; + } + scope 8 { + debug x => _12; + } + } + } + scope 3 { + debug x => _5; + } + scope 4 { + debug x => _6; + } + } + + bb0: { + StorageLive(_1); + StorageLive(_2); + _2 = const {alloc1: &E}; + _1 = (*_2); + StorageDead(_2); + StorageLive(_3); +- _4 = discriminant(_1); +- switchInt(move _4) -> [0: bb3, 1: bb1, otherwise: bb2]; ++ _4 = const 0_isize; ++ switchInt(const 0_isize) -> [0: bb3, 1: bb1, otherwise: bb2]; + } + + bb1: { + StorageLive(_6); + _6 = ((_1 as V2).0: i32); + _3 = _6; + StorageDead(_6); + goto -> bb4; + } + + bb2: { + unreachable; + } + + bb3: { + StorageLive(_5); +- _5 = ((_1 as V1).0: i32); +- _3 = _5; ++ _5 = const 0_i32; ++ _3 = const 0_i32; + StorageDead(_5); + goto -> bb4; + } + + bb4: { + StorageLive(_7); + StorageLive(_8); + _8 = const {alloc2: &&E}; + _7 = (*_8); + StorageDead(_8); + StorageLive(_9); + _10 = discriminant((*_7)); + switchInt(move _10) -> [0: bb6, 1: bb5, otherwise: bb2]; + } + + bb5: { + StorageLive(_12); + _12 = &(((*_7) as V2).0: i32); + _9 = &(*_12); + StorageDead(_12); + goto -> bb7; + } + + bb6: { + StorageLive(_11); + _11 = &(((*_7) as V1).0: i32); + _9 = _11; + StorageDead(_11); + goto -> bb7; + } + + bb7: { + _0 = const (); + StorageDead(_9); + StorageDead(_7); + StorageDead(_3); + StorageDead(_1); + return; + } + } + + alloc2 (static: RC, size: 8, align: 8) { + ╾───────alloc14───────╼ │ ╾──────╼ + } + + alloc14 (size: 8, align: 4) { + 01 00 00 00 04 00 00 00 │ ........ + } + + alloc1 (static: statics::C, size: 8, align: 4) { + 00 00 00 00 00 00 00 00 │ ........ + } + diff --git a/tests/mir-opt/dataflow-const-prop/slice_len.main.DataflowConstProp.32bit.panic-abort.diff b/tests/mir-opt/dataflow-const-prop/slice_len.main.DataflowConstProp.32bit.panic-abort.diff index be55d259dcf..e99b413f708 100644 --- a/tests/mir-opt/dataflow-const-prop/slice_len.main.DataflowConstProp.32bit.panic-abort.diff +++ b/tests/mir-opt/dataflow-const-prop/slice_len.main.DataflowConstProp.32bit.panic-abort.diff @@ -55,11 +55,12 @@ _10 = const _; StorageLive(_11); _11 = const 1_usize; - _12 = Len((*_10)); +- _12 = Len((*_10)); - _13 = Lt(_11, _12); - assert(move _13, "index out of bounds: the length is {} but the index is {}", move _12, _11) -> [success: bb2, unwind unreachable]; -+ _13 = Lt(const 1_usize, _12); -+ assert(move _13, "index out of bounds: the length is {} but the index is {}", move _12, const 1_usize) -> [success: bb2, unwind unreachable]; ++ _12 = const 3_usize; ++ _13 = const true; ++ assert(const true, "index out of bounds: the length is {} but the index is {}", const 3_usize, const 1_usize) -> [success: bb2, unwind unreachable]; } bb2: { diff --git a/tests/mir-opt/dataflow-const-prop/slice_len.main.DataflowConstProp.32bit.panic-unwind.diff b/tests/mir-opt/dataflow-const-prop/slice_len.main.DataflowConstProp.32bit.panic-unwind.diff index f9a6c509ac8..759a793fbf3 100644 --- a/tests/mir-opt/dataflow-const-prop/slice_len.main.DataflowConstProp.32bit.panic-unwind.diff +++ b/tests/mir-opt/dataflow-const-prop/slice_len.main.DataflowConstProp.32bit.panic-unwind.diff @@ -55,11 +55,12 @@ _10 = const _; StorageLive(_11); _11 = const 1_usize; - _12 = Len((*_10)); +- _12 = Len((*_10)); - _13 = Lt(_11, _12); - assert(move _13, "index out of bounds: the length is {} but the index is {}", move _12, _11) -> [success: bb2, unwind continue]; -+ _13 = Lt(const 1_usize, _12); -+ assert(move _13, "index out of bounds: the length is {} but the index is {}", move _12, const 1_usize) -> [success: bb2, unwind continue]; ++ _12 = const 3_usize; ++ _13 = const true; ++ assert(const true, "index out of bounds: the length is {} but the index is {}", const 3_usize, const 1_usize) -> [success: bb2, unwind continue]; } bb2: { diff --git a/tests/mir-opt/dataflow-const-prop/slice_len.main.DataflowConstProp.64bit.panic-abort.diff b/tests/mir-opt/dataflow-const-prop/slice_len.main.DataflowConstProp.64bit.panic-abort.diff index be55d259dcf..e99b413f708 100644 --- a/tests/mir-opt/dataflow-const-prop/slice_len.main.DataflowConstProp.64bit.panic-abort.diff +++ b/tests/mir-opt/dataflow-const-prop/slice_len.main.DataflowConstProp.64bit.panic-abort.diff @@ -55,11 +55,12 @@ _10 = const _; StorageLive(_11); _11 = const 1_usize; - _12 = Len((*_10)); +- _12 = Len((*_10)); - _13 = Lt(_11, _12); - assert(move _13, "index out of bounds: the length is {} but the index is {}", move _12, _11) -> [success: bb2, unwind unreachable]; -+ _13 = Lt(const 1_usize, _12); -+ assert(move _13, "index out of bounds: the length is {} but the index is {}", move _12, const 1_usize) -> [success: bb2, unwind unreachable]; ++ _12 = const 3_usize; ++ _13 = const true; ++ assert(const true, "index out of bounds: the length is {} but the index is {}", const 3_usize, const 1_usize) -> [success: bb2, unwind unreachable]; } bb2: { diff --git a/tests/mir-opt/dataflow-const-prop/slice_len.main.DataflowConstProp.64bit.panic-unwind.diff b/tests/mir-opt/dataflow-const-prop/slice_len.main.DataflowConstProp.64bit.panic-unwind.diff index f9a6c509ac8..759a793fbf3 100644 --- a/tests/mir-opt/dataflow-const-prop/slice_len.main.DataflowConstProp.64bit.panic-unwind.diff +++ b/tests/mir-opt/dataflow-const-prop/slice_len.main.DataflowConstProp.64bit.panic-unwind.diff @@ -55,11 +55,12 @@ _10 = const _; StorageLive(_11); _11 = const 1_usize; - _12 = Len((*_10)); +- _12 = Len((*_10)); - _13 = Lt(_11, _12); - assert(move _13, "index out of bounds: the length is {} but the index is {}", move _12, _11) -> [success: bb2, unwind continue]; -+ _13 = Lt(const 1_usize, _12); -+ assert(move _13, "index out of bounds: the length is {} but the index is {}", move _12, const 1_usize) -> [success: bb2, unwind continue]; ++ _12 = const 3_usize; ++ _13 = const true; ++ assert(const true, "index out of bounds: the length is {} but the index is {}", const 3_usize, const 1_usize) -> [success: bb2, unwind continue]; } bb2: { diff --git a/tests/mir-opt/dataflow-const-prop/struct.main.DataflowConstProp.32bit.diff b/tests/mir-opt/dataflow-const-prop/struct.main.DataflowConstProp.32bit.diff new file mode 100644 index 00000000000..2de6ba307d5 --- /dev/null +++ b/tests/mir-opt/dataflow-const-prop/struct.main.DataflowConstProp.32bit.diff @@ -0,0 +1,129 @@ +- // MIR for `main` before DataflowConstProp ++ // MIR for `main` after DataflowConstProp + + fn main() -> () { + let mut _0: (); + let mut _1: S; + let mut _3: i32; + let mut _5: i32; + let mut _6: i32; + let mut _11: BigStruct; + let mut _16: &&BigStruct; + let mut _17: &BigStruct; + let mut _18: &BigStruct; + let mut _19: &BigStruct; + let mut _20: &BigStruct; + let mut _21: &BigStruct; + scope 1 { + debug s => _1; + let _2: i32; + scope 2 { + debug a => _2; + let _4: i32; + scope 3 { + debug b => _4; + let _7: S; + let _8: u8; + let _9: f32; + let _10: S; + scope 4 { + debug a => _7; + debug b => _8; + debug c => _9; + debug d => _10; + let _12: S; + let _13: u8; + let _14: f32; + let _15: S; + scope 5 { + debug a => _12; + debug b => _13; + debug c => _14; + debug d => _15; + } + } + } + } + } + + bb0: { + StorageLive(_1); + _1 = S(const 1_i32); + StorageLive(_2); + StorageLive(_3); +- _3 = (_1.0: i32); +- _2 = Add(move _3, const 2_i32); ++ _3 = const 1_i32; ++ _2 = const 3_i32; + StorageDead(_3); + (_1.0: i32) = const 3_i32; + StorageLive(_4); + StorageLive(_5); +- _5 = _2; ++ _5 = const 3_i32; + StorageLive(_6); +- _6 = (_1.0: i32); +- _4 = Add(move _5, move _6); ++ _6 = const 3_i32; ++ _4 = const 6_i32; + StorageDead(_6); + StorageDead(_5); + StorageLive(_11); + _11 = const _; + StorageLive(_7); +- _7 = (_11.0: S); ++ _7 = const S(1_i32); + StorageLive(_8); +- _8 = (_11.1: u8); ++ _8 = const 5_u8; + StorageLive(_9); +- _9 = (_11.2: f32); ++ _9 = const 7f32; + StorageLive(_10); +- _10 = (_11.3: S); ++ _10 = const S(13_i32); + StorageDead(_11); + StorageLive(_16); + _16 = const {alloc1: &&BigStruct}; + _17 = deref_copy (*_16); + StorageLive(_12); + _18 = deref_copy (*_16); +- _12 = ((*_18).0: S); ++ _12 = const S(1_i32); + StorageLive(_13); + _19 = deref_copy (*_16); +- _13 = ((*_19).1: u8); ++ _13 = const 5_u8; + StorageLive(_14); + _20 = deref_copy (*_16); +- _14 = ((*_20).2: f32); ++ _14 = const 7f32; + StorageLive(_15); + _21 = deref_copy (*_16); +- _15 = ((*_21).3: S); ++ _15 = const S(13_i32); + StorageDead(_16); + _0 = const (); + StorageDead(_15); + StorageDead(_14); + StorageDead(_13); + StorageDead(_12); + StorageDead(_10); + StorageDead(_9); + StorageDead(_8); + StorageDead(_7); + StorageDead(_4); + StorageDead(_2); + StorageDead(_1); + return; + } + } + + alloc1 (static: STAT, size: 4, align: 4) { + ╾─alloc15─╼ │ ╾──╼ + } + + alloc15 (size: 16, align: 4) { + 01 00 00 00 00 00 e0 40 0d 00 00 00 05 __ __ __ │ .......@.....░░░ + } + diff --git a/tests/mir-opt/dataflow-const-prop/struct.main.DataflowConstProp.64bit.diff b/tests/mir-opt/dataflow-const-prop/struct.main.DataflowConstProp.64bit.diff new file mode 100644 index 00000000000..71a28f2165b --- /dev/null +++ b/tests/mir-opt/dataflow-const-prop/struct.main.DataflowConstProp.64bit.diff @@ -0,0 +1,129 @@ +- // MIR for `main` before DataflowConstProp ++ // MIR for `main` after DataflowConstProp + + fn main() -> () { + let mut _0: (); + let mut _1: S; + let mut _3: i32; + let mut _5: i32; + let mut _6: i32; + let mut _11: BigStruct; + let mut _16: &&BigStruct; + let mut _17: &BigStruct; + let mut _18: &BigStruct; + let mut _19: &BigStruct; + let mut _20: &BigStruct; + let mut _21: &BigStruct; + scope 1 { + debug s => _1; + let _2: i32; + scope 2 { + debug a => _2; + let _4: i32; + scope 3 { + debug b => _4; + let _7: S; + let _8: u8; + let _9: f32; + let _10: S; + scope 4 { + debug a => _7; + debug b => _8; + debug c => _9; + debug d => _10; + let _12: S; + let _13: u8; + let _14: f32; + let _15: S; + scope 5 { + debug a => _12; + debug b => _13; + debug c => _14; + debug d => _15; + } + } + } + } + } + + bb0: { + StorageLive(_1); + _1 = S(const 1_i32); + StorageLive(_2); + StorageLive(_3); +- _3 = (_1.0: i32); +- _2 = Add(move _3, const 2_i32); ++ _3 = const 1_i32; ++ _2 = const 3_i32; + StorageDead(_3); + (_1.0: i32) = const 3_i32; + StorageLive(_4); + StorageLive(_5); +- _5 = _2; ++ _5 = const 3_i32; + StorageLive(_6); +- _6 = (_1.0: i32); +- _4 = Add(move _5, move _6); ++ _6 = const 3_i32; ++ _4 = const 6_i32; + StorageDead(_6); + StorageDead(_5); + StorageLive(_11); + _11 = const _; + StorageLive(_7); +- _7 = (_11.0: S); ++ _7 = const S(1_i32); + StorageLive(_8); +- _8 = (_11.1: u8); ++ _8 = const 5_u8; + StorageLive(_9); +- _9 = (_11.2: f32); ++ _9 = const 7f32; + StorageLive(_10); +- _10 = (_11.3: S); ++ _10 = const S(13_i32); + StorageDead(_11); + StorageLive(_16); + _16 = const {alloc1: &&BigStruct}; + _17 = deref_copy (*_16); + StorageLive(_12); + _18 = deref_copy (*_16); +- _12 = ((*_18).0: S); ++ _12 = const S(1_i32); + StorageLive(_13); + _19 = deref_copy (*_16); +- _13 = ((*_19).1: u8); ++ _13 = const 5_u8; + StorageLive(_14); + _20 = deref_copy (*_16); +- _14 = ((*_20).2: f32); ++ _14 = const 7f32; + StorageLive(_15); + _21 = deref_copy (*_16); +- _15 = ((*_21).3: S); ++ _15 = const S(13_i32); + StorageDead(_16); + _0 = const (); + StorageDead(_15); + StorageDead(_14); + StorageDead(_13); + StorageDead(_12); + StorageDead(_10); + StorageDead(_9); + StorageDead(_8); + StorageDead(_7); + StorageDead(_4); + StorageDead(_2); + StorageDead(_1); + return; + } + } + + alloc1 (static: STAT, size: 8, align: 8) { + ╾───────alloc15───────╼ │ ╾──────╼ + } + + alloc15 (size: 16, align: 4) { + 01 00 00 00 00 00 e0 40 0d 00 00 00 05 __ __ __ │ .......@.....░░░ + } + diff --git a/tests/mir-opt/dataflow-const-prop/struct.main.DataflowConstProp.diff b/tests/mir-opt/dataflow-const-prop/struct.main.DataflowConstProp.diff deleted file mode 100644 index 914bc8ac47e..00000000000 --- a/tests/mir-opt/dataflow-const-prop/struct.main.DataflowConstProp.diff +++ /dev/null @@ -1,51 +0,0 @@ -- // MIR for `main` before DataflowConstProp -+ // MIR for `main` after DataflowConstProp - - fn main() -> () { - let mut _0: (); - let mut _1: S; - let mut _3: i32; - let mut _5: i32; - let mut _6: i32; - scope 1 { - debug s => _1; - let _2: i32; - scope 2 { - debug a => _2; - let _4: i32; - scope 3 { - debug b => _4; - } - } - } - - bb0: { - StorageLive(_1); - _1 = S(const 1_i32); - StorageLive(_2); - StorageLive(_3); -- _3 = (_1.0: i32); -- _2 = Add(move _3, const 2_i32); -+ _3 = const 1_i32; -+ _2 = const 3_i32; - StorageDead(_3); - (_1.0: i32) = const 3_i32; - StorageLive(_4); - StorageLive(_5); -- _5 = _2; -+ _5 = const 3_i32; - StorageLive(_6); -- _6 = (_1.0: i32); -- _4 = Add(move _5, move _6); -+ _6 = const 3_i32; -+ _4 = const 6_i32; - StorageDead(_6); - StorageDead(_5); - _0 = const (); - StorageDead(_4); - StorageDead(_2); - StorageDead(_1); - return; - } - } - diff --git a/tests/mir-opt/dataflow-const-prop/struct.rs b/tests/mir-opt/dataflow-const-prop/struct.rs index 841b279e03e..e92a1676d3f 100644 --- a/tests/mir-opt/dataflow-const-prop/struct.rs +++ b/tests/mir-opt/dataflow-const-prop/struct.rs @@ -1,11 +1,22 @@ // unit-test: DataflowConstProp +// EMIT_MIR_FOR_EACH_BIT_WIDTH +#[derive(Copy, Clone)] struct S(i32); +#[derive(Copy, Clone)] +struct BigStruct(S, u8, f32, S); + // EMIT_MIR struct.main.DataflowConstProp.diff fn main() { let mut s = S(1); let a = s.0 + 2; s.0 = 3; let b = a + s.0; + + const VAL: BigStruct = BigStruct(S(1), 5, 7., S(13)); + let BigStruct(a, b, c, d) = VAL; + + static STAT: &BigStruct = &BigStruct(S(1), 5, 7., S(13)); + let BigStruct(a, b, c, d) = *STAT; } diff --git a/tests/mir-opt/dont_inline_type_id.call.Inline.diff b/tests/mir-opt/dont_inline_type_id.call.Inline.diff new file mode 100644 index 00000000000..80cfe07b0cb --- /dev/null +++ b/tests/mir-opt/dont_inline_type_id.call.Inline.diff @@ -0,0 +1,20 @@ +- // MIR for `call` before Inline ++ // MIR for `call` after Inline + + fn call(_1: &T) -> TypeId { + debug s => _1; + let mut _0: std::any::TypeId; + let mut _2: &T; + + bb0: { + StorageLive(_2); + _2 = &(*_1); + _0 = <T as Any>::type_id(move _2) -> [return: bb1, unwind unreachable]; + } + + bb1: { + StorageDead(_2); + return; + } + } + diff --git a/tests/mir-opt/dont_inline_type_id.rs b/tests/mir-opt/dont_inline_type_id.rs new file mode 100644 index 00000000000..d8a56636094 --- /dev/null +++ b/tests/mir-opt/dont_inline_type_id.rs @@ -0,0 +1,15 @@ +// unit-test: Inline +// compile-flags: --crate-type=lib -C panic=abort + +use std::any::Any; +use std::any::TypeId; + +struct A<T: ?Sized + 'static> { + a: i32, + b: T, +} + +// EMIT_MIR dont_inline_type_id.call.Inline.diff +pub fn call<T: ?Sized + 'static>(s: &T) -> TypeId { + s.type_id() +} diff --git a/tests/mir-opt/enum_opt.cand.EnumSizeOpt.32bit.diff b/tests/mir-opt/enum_opt.cand.EnumSizeOpt.32bit.diff index 9d9a7a1e485..ec5f5c1f1fc 100644 --- a/tests/mir-opt/enum_opt.cand.EnumSizeOpt.32bit.diff +++ b/tests/mir-opt/enum_opt.cand.EnumSizeOpt.32bit.diff @@ -64,5 +64,9 @@ StorageDead(_1); return; } ++ } ++ ++ alloc15 (size: 8, align: 4) { ++ 02 00 00 00 05 20 00 00 │ ..... .. } diff --git a/tests/mir-opt/enum_opt.cand.EnumSizeOpt.64bit.diff b/tests/mir-opt/enum_opt.cand.EnumSizeOpt.64bit.diff index 9d9a7a1e485..9bf8637ec76 100644 --- a/tests/mir-opt/enum_opt.cand.EnumSizeOpt.64bit.diff +++ b/tests/mir-opt/enum_opt.cand.EnumSizeOpt.64bit.diff @@ -64,5 +64,9 @@ StorageDead(_1); return; } ++ } ++ ++ alloc15 (size: 16, align: 8) { ++ 02 00 00 00 00 00 00 00 05 20 00 00 00 00 00 00 │ ......... ...... } diff --git a/tests/mir-opt/enum_opt.unin.EnumSizeOpt.32bit.diff b/tests/mir-opt/enum_opt.unin.EnumSizeOpt.32bit.diff index 4306f38b82a..7dc6d21a907 100644 --- a/tests/mir-opt/enum_opt.unin.EnumSizeOpt.32bit.diff +++ b/tests/mir-opt/enum_opt.unin.EnumSizeOpt.32bit.diff @@ -64,5 +64,9 @@ StorageDead(_1); return; } ++ } ++ ++ alloc14 (size: 8, align: 4) { ++ 05 20 00 00 01 00 00 00 │ . ...... } diff --git a/tests/mir-opt/enum_opt.unin.EnumSizeOpt.64bit.diff b/tests/mir-opt/enum_opt.unin.EnumSizeOpt.64bit.diff index 4306f38b82a..0b000876a86 100644 --- a/tests/mir-opt/enum_opt.unin.EnumSizeOpt.64bit.diff +++ b/tests/mir-opt/enum_opt.unin.EnumSizeOpt.64bit.diff @@ -64,5 +64,9 @@ StorageDead(_1); return; } ++ } ++ ++ alloc14 (size: 16, align: 8) { ++ 05 20 00 00 00 00 00 00 01 00 00 00 00 00 00 00 │ . .............. } diff --git a/tests/mir-opt/generator_drop_cleanup.main-{closure#0}.generator_drop.0.panic-abort.mir b/tests/mir-opt/generator_drop_cleanup.main-{closure#0}.generator_drop.0.panic-abort.mir index acbb7904985..958078b9706 100644 --- a/tests/mir-opt/generator_drop_cleanup.main-{closure#0}.generator_drop.0.panic-abort.mir +++ b/tests/mir-opt/generator_drop_cleanup.main-{closure#0}.generator_drop.0.panic-abort.mir @@ -2,11 +2,7 @@ /* generator_layout = GeneratorLayout { field_tys: { _0: GeneratorSavedTy { - ty: Adt( - std::string::String, - [ - ], - ), + ty: std::string::String, source_info: SourceInfo { span: $DIR/generator_drop_cleanup.rs:11:13: 11:15 (#0), scope: scope[0], diff --git a/tests/mir-opt/generator_drop_cleanup.main-{closure#0}.generator_drop.0.panic-unwind.mir b/tests/mir-opt/generator_drop_cleanup.main-{closure#0}.generator_drop.0.panic-unwind.mir index c17d4421542..7e050e585b1 100644 --- a/tests/mir-opt/generator_drop_cleanup.main-{closure#0}.generator_drop.0.panic-unwind.mir +++ b/tests/mir-opt/generator_drop_cleanup.main-{closure#0}.generator_drop.0.panic-unwind.mir @@ -2,11 +2,7 @@ /* generator_layout = GeneratorLayout { field_tys: { _0: GeneratorSavedTy { - ty: Adt( - std::string::String, - [ - ], - ), + ty: std::string::String, source_info: SourceInfo { span: $DIR/generator_drop_cleanup.rs:11:13: 11:15 (#0), scope: scope[0], diff --git a/tests/mir-opt/generator_tiny.main-{closure#0}.generator_resume.0.mir b/tests/mir-opt/generator_tiny.main-{closure#0}.generator_resume.0.mir index e33f5f59de1..13d703b908c 100644 --- a/tests/mir-opt/generator_tiny.main-{closure#0}.generator_resume.0.mir +++ b/tests/mir-opt/generator_tiny.main-{closure#0}.generator_resume.0.mir @@ -2,11 +2,7 @@ /* generator_layout = GeneratorLayout { field_tys: { _0: GeneratorSavedTy { - ty: Adt( - HasDrop, - [ - ], - ), + ty: HasDrop, source_info: SourceInfo { span: $DIR/generator_tiny.rs:20:13: 20:15 (#0), scope: scope[0], diff --git a/tests/mir-opt/inline_generically_if_sized.call.Inline.diff b/tests/mir-opt/inline_generically_if_sized.call.Inline.diff new file mode 100644 index 00000000000..0cf4565dc99 --- /dev/null +++ b/tests/mir-opt/inline_generically_if_sized.call.Inline.diff @@ -0,0 +1,24 @@ +- // MIR for `call` before Inline ++ // MIR for `call` after Inline + + fn call(_1: &T) -> i32 { + debug s => _1; + let mut _0: i32; + let mut _2: &T; ++ scope 1 (inlined <T as Foo>::bar) { ++ debug self => _2; ++ } + + bb0: { + StorageLive(_2); + _2 = &(*_1); +- _0 = <T as Foo>::bar(move _2) -> [return: bb1, unwind unreachable]; +- } +- +- bb1: { ++ _0 = const 0_i32; + StorageDead(_2); + return; + } + } + diff --git a/tests/mir-opt/inline_generically_if_sized.rs b/tests/mir-opt/inline_generically_if_sized.rs new file mode 100644 index 00000000000..1acfff7a56b --- /dev/null +++ b/tests/mir-opt/inline_generically_if_sized.rs @@ -0,0 +1,17 @@ +// unit-test: Inline +// compile-flags: --crate-type=lib -C panic=abort + +trait Foo { + fn bar(&self) -> i32; +} + +impl<T> Foo for T { + fn bar(&self) -> i32 { + 0 + } +} + +// EMIT_MIR inline_generically_if_sized.call.Inline.diff +pub fn call<T>(s: &T) -> i32 { + s.bar() +} diff --git a/tests/mir-opt/issue_99325.main.built.after.32bit.mir b/tests/mir-opt/issue_99325.main.built.after.32bit.mir index b6a673b6355..132b713356e 100644 --- a/tests/mir-opt/issue_99325.main.built.after.32bit.mir +++ b/tests/mir-opt/issue_99325.main.built.after.32bit.mir @@ -1,8 +1,8 @@ // MIR for `main` after built | User Type Annotations -| 0: user_ty: Canonical { value: TypeOf(DefId(0:3 ~ issue_99325[22bb]::function_with_bytes), UserArgs { args: [Const { ty: &ReStatic [u8; Const { ty: usize, kind: Leaf(0x00000004) }], kind: Branch([Leaf(0x41), Leaf(0x41), Leaf(0x41), Leaf(0x41)]) }], user_self_ty: None }), max_universe: U0, variables: [] }, span: $DIR/issue_99325.rs:12:16: 12:46, inferred_ty: fn() -> &'static [u8] {function_with_bytes::<&*b"AAAA">} -| 1: user_ty: Canonical { value: TypeOf(DefId(0:3 ~ issue_99325[22bb]::function_with_bytes), UserArgs { args: [Const { ty: &ReStatic [u8; Const { ty: usize, kind: Leaf(0x00000004) }], kind: UnevaluatedConst { def: DefId(0:8 ~ issue_99325[22bb]::main::{constant#1}), args: [] } }], user_self_ty: None }), max_universe: U0, variables: [] }, span: $DIR/issue_99325.rs:13:16: 13:68, inferred_ty: fn() -> &'static [u8] {function_with_bytes::<&*b"AAAA">} +| 0: user_ty: Canonical { value: TypeOf(DefId(0:3 ~ issue_99325[22bb]::function_with_bytes), UserArgs { args: [&*b"AAAA"], user_self_ty: None }), max_universe: U0, variables: [] }, span: $DIR/issue_99325.rs:12:16: 12:46, inferred_ty: fn() -> &'static [u8] {function_with_bytes::<&*b"AAAA">} +| 1: user_ty: Canonical { value: TypeOf(DefId(0:3 ~ issue_99325[22bb]::function_with_bytes), UserArgs { args: [UnevaluatedConst { def: DefId(0:8 ~ issue_99325[22bb]::main::{constant#1}), args: [] }: &ReStatic [u8; 4_usize]], user_self_ty: None }), max_universe: U0, variables: [] }, span: $DIR/issue_99325.rs:13:16: 13:68, inferred_ty: fn() -> &'static [u8] {function_with_bytes::<&*b"AAAA">} | fn main() -> () { let mut _0: (); diff --git a/tests/mir-opt/issue_99325.main.built.after.64bit.mir b/tests/mir-opt/issue_99325.main.built.after.64bit.mir index 9d112cfa20a..132b713356e 100644 --- a/tests/mir-opt/issue_99325.main.built.after.64bit.mir +++ b/tests/mir-opt/issue_99325.main.built.after.64bit.mir @@ -1,8 +1,8 @@ // MIR for `main` after built | User Type Annotations -| 0: user_ty: Canonical { value: TypeOf(DefId(0:3 ~ issue_99325[22bb]::function_with_bytes), UserArgs { args: [Const { ty: &ReStatic [u8; Const { ty: usize, kind: Leaf(0x0000000000000004) }], kind: Branch([Leaf(0x41), Leaf(0x41), Leaf(0x41), Leaf(0x41)]) }], user_self_ty: None }), max_universe: U0, variables: [] }, span: $DIR/issue_99325.rs:12:16: 12:46, inferred_ty: fn() -> &'static [u8] {function_with_bytes::<&*b"AAAA">} -| 1: user_ty: Canonical { value: TypeOf(DefId(0:3 ~ issue_99325[22bb]::function_with_bytes), UserArgs { args: [Const { ty: &ReStatic [u8; Const { ty: usize, kind: Leaf(0x0000000000000004) }], kind: UnevaluatedConst { def: DefId(0:8 ~ issue_99325[22bb]::main::{constant#1}), args: [] } }], user_self_ty: None }), max_universe: U0, variables: [] }, span: $DIR/issue_99325.rs:13:16: 13:68, inferred_ty: fn() -> &'static [u8] {function_with_bytes::<&*b"AAAA">} +| 0: user_ty: Canonical { value: TypeOf(DefId(0:3 ~ issue_99325[22bb]::function_with_bytes), UserArgs { args: [&*b"AAAA"], user_self_ty: None }), max_universe: U0, variables: [] }, span: $DIR/issue_99325.rs:12:16: 12:46, inferred_ty: fn() -> &'static [u8] {function_with_bytes::<&*b"AAAA">} +| 1: user_ty: Canonical { value: TypeOf(DefId(0:3 ~ issue_99325[22bb]::function_with_bytes), UserArgs { args: [UnevaluatedConst { def: DefId(0:8 ~ issue_99325[22bb]::main::{constant#1}), args: [] }: &ReStatic [u8; 4_usize]], user_self_ty: None }), max_universe: U0, variables: [] }, span: $DIR/issue_99325.rs:13:16: 13:68, inferred_ty: fn() -> &'static [u8] {function_with_bytes::<&*b"AAAA">} | fn main() -> () { let mut _0: (); diff --git a/tests/mir-opt/nll/region_subtyping_basic.main.nll.0.32bit.mir b/tests/mir-opt/nll/region_subtyping_basic.main.nll.0.32bit.mir index 56b0f816573..c581d0f8471 100644 --- a/tests/mir-opt/nll/region_subtyping_basic.main.nll.0.32bit.mir +++ b/tests/mir-opt/nll/region_subtyping_basic.main.nll.0.32bit.mir @@ -22,7 +22,7 @@ | fn main() -> () { let mut _0: (); - let mut _1: [usize; Const { ty: usize, kind: Leaf(0x00000003) }]; + let mut _1: [usize; ValTree(Leaf(0x00000003): usize)]; let _3: usize; let mut _4: usize; let mut _5: bool; diff --git a/tests/mir-opt/nll/region_subtyping_basic.main.nll.0.64bit.mir b/tests/mir-opt/nll/region_subtyping_basic.main.nll.0.64bit.mir index 83b851eed74..48243e34d08 100644 --- a/tests/mir-opt/nll/region_subtyping_basic.main.nll.0.64bit.mir +++ b/tests/mir-opt/nll/region_subtyping_basic.main.nll.0.64bit.mir @@ -22,7 +22,7 @@ | fn main() -> () { let mut _0: (); - let mut _1: [usize; Const { ty: usize, kind: Leaf(0x0000000000000003) }]; + let mut _1: [usize; ValTree(Leaf(0x0000000000000003): usize)]; let _3: usize; let mut _4: usize; let mut _5: bool; diff --git a/tests/mir-opt/pre-codegen/optimizes_into_variable.main.ConstProp.32bit.panic-abort.diff b/tests/mir-opt/pre-codegen/optimizes_into_variable.main.ConstProp.32bit.panic-abort.diff index 2c607b4c055..681e9666e0f 100644 --- a/tests/mir-opt/pre-codegen/optimizes_into_variable.main.ConstProp.32bit.panic-abort.diff +++ b/tests/mir-opt/pre-codegen/optimizes_into_variable.main.ConstProp.32bit.panic-abort.diff @@ -55,5 +55,9 @@ StorageDead(_1); return; } ++ } ++ ++ alloc5 (size: 8, align: 4) { ++ 04 00 00 00 00 __ __ __ │ .....░░░ } diff --git a/tests/mir-opt/pre-codegen/optimizes_into_variable.main.ConstProp.32bit.panic-unwind.diff b/tests/mir-opt/pre-codegen/optimizes_into_variable.main.ConstProp.32bit.panic-unwind.diff index b6929f3f93c..db16b8d82d2 100644 --- a/tests/mir-opt/pre-codegen/optimizes_into_variable.main.ConstProp.32bit.panic-unwind.diff +++ b/tests/mir-opt/pre-codegen/optimizes_into_variable.main.ConstProp.32bit.panic-unwind.diff @@ -55,5 +55,9 @@ StorageDead(_1); return; } ++ } ++ ++ alloc5 (size: 8, align: 4) { ++ 04 00 00 00 00 __ __ __ │ .....░░░ } diff --git a/tests/mir-opt/pre-codegen/optimizes_into_variable.main.ConstProp.64bit.panic-abort.diff b/tests/mir-opt/pre-codegen/optimizes_into_variable.main.ConstProp.64bit.panic-abort.diff index 2c607b4c055..681e9666e0f 100644 --- a/tests/mir-opt/pre-codegen/optimizes_into_variable.main.ConstProp.64bit.panic-abort.diff +++ b/tests/mir-opt/pre-codegen/optimizes_into_variable.main.ConstProp.64bit.panic-abort.diff @@ -55,5 +55,9 @@ StorageDead(_1); return; } ++ } ++ ++ alloc5 (size: 8, align: 4) { ++ 04 00 00 00 00 __ __ __ │ .....░░░ } diff --git a/tests/mir-opt/pre-codegen/optimizes_into_variable.main.ConstProp.64bit.panic-unwind.diff b/tests/mir-opt/pre-codegen/optimizes_into_variable.main.ConstProp.64bit.panic-unwind.diff index b6929f3f93c..db16b8d82d2 100644 --- a/tests/mir-opt/pre-codegen/optimizes_into_variable.main.ConstProp.64bit.panic-unwind.diff +++ b/tests/mir-opt/pre-codegen/optimizes_into_variable.main.ConstProp.64bit.panic-unwind.diff @@ -55,5 +55,9 @@ StorageDead(_1); return; } ++ } ++ ++ alloc5 (size: 8, align: 4) { ++ 04 00 00 00 00 __ __ __ │ .....░░░ } diff --git a/tests/mir-opt/pre-codegen/spans.outer.PreCodegen.after.panic-abort.mir b/tests/mir-opt/pre-codegen/spans.outer.PreCodegen.after.panic-abort.mir index 1d3405a9afe..18a663d9f9e 100644 --- a/tests/mir-opt/pre-codegen/spans.outer.PreCodegen.after.panic-abort.mir +++ b/tests/mir-opt/pre-codegen/spans.outer.PreCodegen.after.panic-abort.mir @@ -11,7 +11,7 @@ fn outer(_1: u8) -> u8 { _0 = inner(move _2) -> [return: bb1, unwind unreachable]; // scope 0 at $DIR/spans.rs:10:5: 10:14 // mir::Constant // + span: $DIR/spans.rs:10:5: 10:10 - // + literal: Const { ty: for<'a> fn(&'a u8) -> u8 {inner}, val: Value(<ZST>) } + // + literal: Const { ty: for<'a> fn(&'a u8) -> u8 {inner}, val: Value(inner) } } bb1: { diff --git a/tests/mir-opt/pre-codegen/spans.outer.PreCodegen.after.panic-unwind.mir b/tests/mir-opt/pre-codegen/spans.outer.PreCodegen.after.panic-unwind.mir index 285b6e41314..1c02fb72bcd 100644 --- a/tests/mir-opt/pre-codegen/spans.outer.PreCodegen.after.panic-unwind.mir +++ b/tests/mir-opt/pre-codegen/spans.outer.PreCodegen.after.panic-unwind.mir @@ -11,7 +11,7 @@ fn outer(_1: u8) -> u8 { _0 = inner(move _2) -> [return: bb1, unwind continue]; // scope 0 at $DIR/spans.rs:10:5: 10:14 // mir::Constant // + span: $DIR/spans.rs:10:5: 10:10 - // + literal: Const { ty: for<'a> fn(&'a u8) -> u8 {inner}, val: Value(<ZST>) } + // + literal: Const { ty: for<'a> fn(&'a u8) -> u8 {inner}, val: Value(inner) } } bb1: { diff --git a/tests/pretty/tests-are-sorted.pp b/tests/pretty/tests-are-sorted.pp index 7d7f682130d..fd9386be8f3 100644 --- a/tests/pretty/tests-are-sorted.pp +++ b/tests/pretty/tests-are-sorted.pp @@ -79,7 +79,7 @@ pub const a_test: test::TestDescAndFn = }; fn a_test() {} #[rustc_main] -#[no_coverage] +#[coverage(off)] pub fn main() -> () { extern crate test; test::test_main_static(&[&a_test, &m_test, &z_test]) diff --git a/tests/run-coverage/closure.coverage b/tests/run-coverage/closure.coverage index 930348dc431..67014f792c8 100644 --- a/tests/run-coverage/closure.coverage +++ b/tests/run-coverage/closure.coverage @@ -76,8 +76,8 @@ LL| 1| some_string = None; LL| 1| let LL| 1| a - LL| 1| = - LL| 1| || + LL| | = + LL| | || LL| 1| { LL| 1| let mut countdown = 0; LL| 1| if is_false { @@ -98,8 +98,8 @@ LL| 1| LL| 1| let LL| 1| quote_closure - LL| 1| = - LL| 1| |val| + LL| | = + LL| | |val| LL| 5| { LL| 5| let mut countdown = 0; LL| 5| if is_false { @@ -186,7 +186,7 @@ LL| | ; LL| | LL| 1| let short_used_not_covered_closure_line_break_block_embedded_branch = - LL| 1| | _unused_arg: u8 | + LL| | | _unused_arg: u8 | LL| 0| { LL| 0| println!( LL| 0| "not called: {}", @@ -196,7 +196,7 @@ LL| | ; LL| | LL| 1| let short_used_covered_closure_line_break_no_block_embedded_branch = - LL| 1| | _unused_arg: u8 | + LL| | | _unused_arg: u8 | LL| 1| println!( LL| 1| "not called: {}", LL| 1| if is_true { "check" } else { "me" } @@ -205,7 +205,7 @@ LL| | ; LL| | LL| 1| let short_used_covered_closure_line_break_block_embedded_branch = - LL| 1| | _unused_arg: u8 | + LL| | | _unused_arg: u8 | LL| 1| { LL| 1| println!( LL| 1| "not called: {}", diff --git a/tests/run-coverage/closure_bug.coverage b/tests/run-coverage/closure_bug.coverage new file mode 100644 index 00000000000..f3299834bce --- /dev/null +++ b/tests/run-coverage/closure_bug.coverage @@ -0,0 +1,53 @@ + LL| |// Regression test for #115930. + LL| |// All of these closures are identical, and should produce identical output in + LL| |// the coverage report. However, an unstable sort was causing them to be treated + LL| |// inconsistently when preparing coverage spans. + LL| | + LL| 1|fn main() { + LL| 1| let truthy = std::env::args().len() == 1; + LL| 1| + LL| 1| let a + LL| | = + LL| | | + LL| | | + LL| 2| if truthy { true } else { false }; + ^0 + LL| | + LL| 1| a(); + LL| 1| if truthy { a(); } + ^0 + LL| | + LL| 1| let b + LL| | = + LL| | | + LL| | | + LL| 2| if truthy { true } else { false }; + ^0 + LL| | + LL| 1| b(); + LL| 1| if truthy { b(); } + ^0 + LL| | + LL| 1| let c + LL| | = + LL| | | + LL| | | + LL| 2| if truthy { true } else { false }; + ^0 + LL| | + LL| 1| c(); + LL| 1| if truthy { c(); } + ^0 + LL| | + LL| 1| let d + LL| | = + LL| | | + LL| | | + LL| 2| if truthy { true } else { false }; + ^0 + LL| | + LL| 1| d(); + LL| 1| if truthy { d(); } + ^0 + LL| 1|} + diff --git a/tests/run-coverage/closure_bug.rs b/tests/run-coverage/closure_bug.rs new file mode 100644 index 00000000000..739bc5f0b51 --- /dev/null +++ b/tests/run-coverage/closure_bug.rs @@ -0,0 +1,44 @@ +// Regression test for #115930. +// All of these closures are identical, and should produce identical output in +// the coverage report. However, an unstable sort was causing them to be treated +// inconsistently when preparing coverage spans. + +fn main() { + let truthy = std::env::args().len() == 1; + + let a + = + | + | + if truthy { true } else { false }; + + a(); + if truthy { a(); } + + let b + = + | + | + if truthy { true } else { false }; + + b(); + if truthy { b(); } + + let c + = + | + | + if truthy { true } else { false }; + + c(); + if truthy { c(); } + + let d + = + | + | + if truthy { true } else { false }; + + d(); + if truthy { d(); } +} diff --git a/tests/run-coverage/closure_macro.coverage b/tests/run-coverage/closure_macro.coverage index 1bfd2013da8..0f2c917e090 100644 --- a/tests/run-coverage/closure_macro.coverage +++ b/tests/run-coverage/closure_macro.coverage @@ -1,5 +1,5 @@ LL| |// compile-flags: --edition=2018 - LL| |#![feature(no_coverage)] + LL| |#![feature(coverage_attribute)] LL| | LL| |macro_rules! bail { LL| | ($msg:literal $(,)?) => { diff --git a/tests/run-coverage/closure_macro.rs b/tests/run-coverage/closure_macro.rs index 5e3b00d1ef5..9b289141c2e 100644 --- a/tests/run-coverage/closure_macro.rs +++ b/tests/run-coverage/closure_macro.rs @@ -1,5 +1,5 @@ // compile-flags: --edition=2018 -#![feature(no_coverage)] +#![feature(coverage_attribute)] macro_rules! bail { ($msg:literal $(,)?) => { diff --git a/tests/run-coverage/closure_macro_async.coverage b/tests/run-coverage/closure_macro_async.coverage index 018e3160e4f..74247f1bc6f 100644 --- a/tests/run-coverage/closure_macro_async.coverage +++ b/tests/run-coverage/closure_macro_async.coverage @@ -1,5 +1,5 @@ LL| |// compile-flags: --edition=2018 - LL| |#![feature(no_coverage)] + LL| |#![feature(coverage_attribute)] LL| | LL| |macro_rules! bail { LL| | ($msg:literal $(,)?) => { @@ -40,7 +40,7 @@ LL| 1| Ok(()) LL| 1|} LL| | - LL| |#[no_coverage] + LL| |#[coverage(off)] LL| |fn main() { LL| | executor::block_on(test()).unwrap(); LL| |} @@ -52,18 +52,18 @@ LL| | task::{Context, Poll, RawWaker, RawWakerVTable, Waker}, LL| | }; LL| | - LL| | #[no_coverage] + LL| | #[coverage(off)] LL| | pub fn block_on<F: Future>(mut future: F) -> F::Output { LL| | let mut future = unsafe { Pin::new_unchecked(&mut future) }; LL| | use std::hint::unreachable_unchecked; LL| | static VTABLE: RawWakerVTable = RawWakerVTable::new( - LL| | #[no_coverage] + LL| | #[coverage(off)] LL| | |_| unsafe { unreachable_unchecked() }, // clone - LL| | #[no_coverage] + LL| | #[coverage(off)] LL| | |_| unsafe { unreachable_unchecked() }, // wake - LL| | #[no_coverage] + LL| | #[coverage(off)] LL| | |_| unsafe { unreachable_unchecked() }, // wake_by_ref - LL| | #[no_coverage] + LL| | #[coverage(off)] LL| | |_| (), LL| | ); LL| | let waker = unsafe { Waker::from_raw(RawWaker::new(core::ptr::null(), &VTABLE)) }; diff --git a/tests/run-coverage/closure_macro_async.rs b/tests/run-coverage/closure_macro_async.rs index 3d6bdb38a2a..b4275599e59 100644 --- a/tests/run-coverage/closure_macro_async.rs +++ b/tests/run-coverage/closure_macro_async.rs @@ -1,5 +1,5 @@ // compile-flags: --edition=2018 -#![feature(no_coverage)] +#![feature(coverage_attribute)] macro_rules! bail { ($msg:literal $(,)?) => { @@ -39,7 +39,7 @@ pub async fn test() -> Result<(), String> { Ok(()) } -#[no_coverage] +#[coverage(off)] fn main() { executor::block_on(test()).unwrap(); } @@ -51,18 +51,18 @@ mod executor { task::{Context, Poll, RawWaker, RawWakerVTable, Waker}, }; - #[no_coverage] + #[coverage(off)] pub fn block_on<F: Future>(mut future: F) -> F::Output { let mut future = unsafe { Pin::new_unchecked(&mut future) }; use std::hint::unreachable_unchecked; static VTABLE: RawWakerVTable = RawWakerVTable::new( - #[no_coverage] + #[coverage(off)] |_| unsafe { unreachable_unchecked() }, // clone - #[no_coverage] + #[coverage(off)] |_| unsafe { unreachable_unchecked() }, // wake - #[no_coverage] + #[coverage(off)] |_| unsafe { unreachable_unchecked() }, // wake_by_ref - #[no_coverage] + #[coverage(off)] |_| (), ); let waker = unsafe { Waker::from_raw(RawWaker::new(core::ptr::null(), &VTABLE)) }; diff --git a/tests/run-coverage/no_cov_crate.coverage b/tests/run-coverage/no_cov_crate.coverage index 73f6fbd0c2b..f5a0322bf3e 100644 --- a/tests/run-coverage/no_cov_crate.coverage +++ b/tests/run-coverage/no_cov_crate.coverage @@ -1,17 +1,17 @@ - LL| |// Enables `no_coverage` on the entire crate - LL| |#![feature(no_coverage)] + LL| |// Enables `coverage(off)` on the entire crate + LL| |#![feature(coverage_attribute)] LL| | - LL| |#[no_coverage] + LL| |#[coverage(off)] LL| |fn do_not_add_coverage_1() { LL| | println!("called but not covered"); LL| |} LL| | LL| |fn do_not_add_coverage_2() { - LL| | #![no_coverage] + LL| | #![coverage(off)] LL| | println!("called but not covered"); LL| |} LL| | - LL| |#[no_coverage] + LL| |#[coverage(off)] LL| |#[allow(dead_code)] LL| |fn do_not_add_coverage_not_called() { LL| | println!("not called and not covered"); @@ -33,7 +33,7 @@ LL| |// FIXME: These test-cases illustrate confusing results of nested functions. LL| |// See https://github.com/rust-lang/rust/issues/93319 LL| |mod nested_fns { - LL| | #[no_coverage] + LL| | #[coverage(off)] LL| | pub fn outer_not_covered(is_true: bool) { LL| 1| fn inner(is_true: bool) { LL| 1| if is_true { @@ -50,7 +50,7 @@ LL| 1| println!("called and covered"); LL| 1| inner_not_covered(is_true); LL| 1| - LL| 1| #[no_coverage] + LL| 1| #[coverage(off)] LL| 1| fn inner_not_covered(is_true: bool) { LL| 1| if is_true { LL| 1| println!("called but not covered"); diff --git a/tests/run-coverage/no_cov_crate.rs b/tests/run-coverage/no_cov_crate.rs index 5b748aeefb7..e12e4bc55e3 100644 --- a/tests/run-coverage/no_cov_crate.rs +++ b/tests/run-coverage/no_cov_crate.rs @@ -1,17 +1,17 @@ -// Enables `no_coverage` on the entire crate -#![feature(no_coverage)] +// Enables `coverage(off)` on the entire crate +#![feature(coverage_attribute)] -#[no_coverage] +#[coverage(off)] fn do_not_add_coverage_1() { println!("called but not covered"); } fn do_not_add_coverage_2() { - #![no_coverage] + #![coverage(off)] println!("called but not covered"); } -#[no_coverage] +#[coverage(off)] #[allow(dead_code)] fn do_not_add_coverage_not_called() { println!("not called and not covered"); @@ -33,7 +33,7 @@ fn add_coverage_not_called() { // FIXME: These test-cases illustrate confusing results of nested functions. // See https://github.com/rust-lang/rust/issues/93319 mod nested_fns { - #[no_coverage] + #[coverage(off)] pub fn outer_not_covered(is_true: bool) { fn inner(is_true: bool) { if is_true { @@ -50,7 +50,7 @@ mod nested_fns { println!("called and covered"); inner_not_covered(is_true); - #[no_coverage] + #[coverage(off)] fn inner_not_covered(is_true: bool) { if is_true { println!("called but not covered"); diff --git a/tests/run-make-fulldeps/obtain-borrowck/driver.rs b/tests/run-make-fulldeps/obtain-borrowck/driver.rs index 04c551cf4bb..b59a65a713f 100644 --- a/tests/run-make-fulldeps/obtain-borrowck/driver.rs +++ b/tests/run-make-fulldeps/obtain-borrowck/driver.rs @@ -27,7 +27,7 @@ use rustc_interface::{Config, Queries}; use rustc_middle::query::queries::mir_borrowck::ProvidedValue; use rustc_middle::query::{ExternProviders, Providers}; use rustc_middle::ty::TyCtxt; -use rustc_session::{Session, EarlyErrorHandler}; +use rustc_session::Session; use std::cell::RefCell; use std::collections::HashMap; use std::thread_local; @@ -58,7 +58,6 @@ impl rustc_driver::Callbacks for CompilerCalls { // the result. fn after_analysis<'tcx>( &mut self, - _handler: &EarlyErrorHandler, compiler: &Compiler, queries: &'tcx Queries<'tcx>, ) -> Compilation { diff --git a/tests/run-make/dump-ice-to-disk/check.sh b/tests/run-make/dump-ice-to-disk/check.sh index 91109596a45..ab6f9ab6018 100644 --- a/tests/run-make/dump-ice-to-disk/check.sh +++ b/tests/run-make/dump-ice-to-disk/check.sh @@ -22,8 +22,8 @@ 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 | wc -l) -should_be_empty_dot=$(ls -l ./rustc-ice-*.txt | wc -l) +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 diff --git a/tests/run-make/emit-path-unhashed/Makefile b/tests/run-make/emit-path-unhashed/Makefile index 74047fe5f86..611f8578140 100644 --- a/tests/run-make/emit-path-unhashed/Makefile +++ b/tests/run-make/emit-path-unhashed/Makefile @@ -5,10 +5,10 @@ OUT=$(TMPDIR)/emit # --emit KIND=PATH should not affect crate hash vs --emit KIND all: $(OUT)/a/libfoo.rlib $(OUT)/b/libfoo.rlib $(OUT)/c/libfoo.rlib \ $(TMPDIR)/libfoo.rlib - $(RUSTC) -Zls $(TMPDIR)/libfoo.rlib > $(TMPDIR)/base.txt - $(RUSTC) -Zls $(OUT)/a/libfoo.rlib > $(TMPDIR)/a.txt - $(RUSTC) -Zls $(OUT)/b/libfoo.rlib > $(TMPDIR)/b.txt - $(RUSTC) -Zls $(OUT)/c/libfoo.rlib > $(TMPDIR)/c.txt + $(RUSTC) -Zls=root $(TMPDIR)/libfoo.rlib > $(TMPDIR)/base.txt + $(RUSTC) -Zls=root $(OUT)/a/libfoo.rlib > $(TMPDIR)/a.txt + $(RUSTC) -Zls=root $(OUT)/b/libfoo.rlib > $(TMPDIR)/b.txt + $(RUSTC) -Zls=root $(OUT)/c/libfoo.rlib > $(TMPDIR)/c.txt diff $(TMPDIR)/base.txt $(TMPDIR)/a.txt diff $(TMPDIR)/base.txt $(TMPDIR)/b.txt diff --git a/tests/run-make/issue-88756-default-output/output-default.stdout b/tests/run-make/issue-88756-default-output/output-default.stdout index de8ff0e5f89..f5981045b03 100644 --- a/tests/run-make/issue-88756-default-output/output-default.stdout +++ b/tests/run-make/issue-88756-default-output/output-default.stdout @@ -100,7 +100,7 @@ Options: check if given theme is valid --resource-suffix PATH suffix to add to CSS and JavaScript files, e.g., - "light.css" will become "light-suffix.css" + "search-index.js" will become "search-index-suffix.js" --edition EDITION edition to use when compiling rust code (default: 2015) diff --git a/tests/run-make/ls-metadata/Makefile b/tests/run-make/ls-metadata/Makefile index 123dd64e15c..f03569baef7 100644 --- a/tests/run-make/ls-metadata/Makefile +++ b/tests/run-make/ls-metadata/Makefile @@ -3,6 +3,6 @@ include ../tools.mk all: $(RUSTC) foo.rs - $(RUSTC) -Z ls $(TMPDIR)/foo + $(RUSTC) -Z ls=root $(TMPDIR)/foo touch $(TMPDIR)/bar - $(RUSTC) -Z ls $(TMPDIR)/bar + $(RUSTC) -Z ls=root $(TMPDIR)/bar diff --git a/tests/run-make/lto-linkage-used-attr/Makefile b/tests/run-make/lto-linkage-used-attr/Makefile new file mode 100644 index 00000000000..e78b83890ed --- /dev/null +++ b/tests/run-make/lto-linkage-used-attr/Makefile @@ -0,0 +1,9 @@ +include ../tools.mk + +# Verify that the impl_* symbols are preserved. #108030 +# only-x86_64-unknown-linux-gnu +# min-llvm-version: 17 + +all: + $(RUSTC) -Cdebuginfo=0 -Copt-level=3 lib.rs + $(RUSTC) -Clto=fat -Cdebuginfo=0 -Copt-level=3 main.rs diff --git a/tests/run-make/lto-linkage-used-attr/lib.rs b/tests/run-make/lto-linkage-used-attr/lib.rs new file mode 100644 index 00000000000..0a92ea9cd22 --- /dev/null +++ b/tests/run-make/lto-linkage-used-attr/lib.rs @@ -0,0 +1,50 @@ +#![crate_type = "rlib"] +#![crate_type = "cdylib"] + +#[macro_export] +macro_rules! asm_func { + ($name:expr, $body:expr $(, $($args:tt)*)?) => { + core::arch::global_asm!( + concat!( + ".p2align 4\n", + ".hidden ", $name, "\n", + ".global ", $name, "\n", + ".type ", $name, ",@function\n", + $name, ":\n", + $body, + ".size ", $name, ",.-", $name, + ) + $(, $($args)*)? + ); + }; +} + +macro_rules! libcall_trampoline { + ($libcall:ident ; $libcall_impl:ident) => { + asm_func!( + stringify!($libcall), + concat!( + " + .cfi_startproc simple + .cfi_def_cfa_offset 0 + jmp {} + .cfi_endproc + ", + ), + sym $libcall_impl + ); + }; +} + +pub mod trampolines { + extern "C" { + pub fn table_fill_funcref(); + pub fn table_fill_externref(); + } + + unsafe extern "C" fn impl_table_fill_funcref() {} + unsafe extern "C" fn impl_table_fill_externref() {} + + libcall_trampoline!(table_fill_funcref ; impl_table_fill_funcref); + libcall_trampoline!(table_fill_externref ; impl_table_fill_externref); +} diff --git a/tests/run-make/lto-linkage-used-attr/main.rs b/tests/run-make/lto-linkage-used-attr/main.rs new file mode 100644 index 00000000000..256b02e5b0b --- /dev/null +++ b/tests/run-make/lto-linkage-used-attr/main.rs @@ -0,0 +1,10 @@ +extern crate lib; + +use lib::trampolines::*; + +fn main() { + unsafe { + table_fill_externref(); + table_fill_funcref(); + } +} diff --git a/tests/run-make/metadata-dep-info/Makefile b/tests/run-make/metadata-dep-info/Makefile new file mode 100644 index 00000000000..f9043f21433 --- /dev/null +++ b/tests/run-make/metadata-dep-info/Makefile @@ -0,0 +1,13 @@ +include ../tools.mk + +ifdef RUSTC_BLESS_TEST + RUSTC_TEST_OP = cp +else + RUSTC_TEST_OP = $(DIFF) +endif + +all: + $(RUSTC) --emit=metadata,dep-info --crate-type lib dash-separated.rs -C extra-filename=_something-extra + # Strip TMPDIR since it is a machine specific absolute path + sed "s%.*[/\\]%%" "$(TMPDIR)"/dash-separated_something-extra.d > "$(TMPDIR)"/dash-separated_something-extra.normalized.d + $(RUSTC_TEST_OP) "$(TMPDIR)"/dash-separated_something-extra.normalized.d dash-separated_something-extra.normalized.d diff --git a/tests/run-make/metadata-dep-info/dash-separated.rs b/tests/run-make/metadata-dep-info/dash-separated.rs new file mode 100644 index 00000000000..4202afd3d08 --- /dev/null +++ b/tests/run-make/metadata-dep-info/dash-separated.rs @@ -0,0 +1,4 @@ +//! It is important that this file has at least one `-` in the file name since +//! we want to test that it becomes a `_` when appropriate. + +pub struct Foo; diff --git a/tests/run-make/metadata-dep-info/dash-separated_something-extra.normalized.d b/tests/run-make/metadata-dep-info/dash-separated_something-extra.normalized.d new file mode 100644 index 00000000000..497d76b4ea1 --- /dev/null +++ b/tests/run-make/metadata-dep-info/dash-separated_something-extra.normalized.d @@ -0,0 +1,5 @@ +libdash_separated_something-extra.rmeta: dash-separated.rs + +dash-separated_something-extra.d: dash-separated.rs + +dash-separated.rs: diff --git a/tests/run-make/output-filename-overwrites-input/Makefile b/tests/run-make/output-filename-overwrites-input/Makefile index 605b86b253e..fe5d231382d 100644 --- a/tests/run-make/output-filename-overwrites-input/Makefile +++ b/tests/run-make/output-filename-overwrites-input/Makefile @@ -8,7 +8,7 @@ all: cp bar.rs $(TMPDIR)/bar.rlib $(RUSTC) $(TMPDIR)/bar.rlib -o $(TMPDIR)/bar.rlib 2>&1 \ | $(CGREP) -e "the input file \".*bar.rlib\" would be overwritten by the generated executable" - $(RUSTC) foo.rs 2>&1 && $(RUSTC) -Z ls $(TMPDIR)/foo 2>&1 + $(RUSTC) foo.rs 2>&1 && $(RUSTC) -Z ls=root $(TMPDIR)/foo 2>&1 cp foo.rs $(TMPDIR)/foo.rs $(RUSTC) $(TMPDIR)/foo.rs -o $(TMPDIR)/foo.rs 2>&1 \ | $(CGREP) -e "the input file \".*foo.rs\" would be overwritten by the generated executable" diff --git a/tests/run-make/rustdoc-themes/Makefile b/tests/run-make/rustdoc-themes/Makefile index a6d9a43addf..a4980eb0b3e 100644 --- a/tests/run-make/rustdoc-themes/Makefile +++ b/tests/run-make/rustdoc-themes/Makefile @@ -5,6 +5,7 @@ include ../tools.mk OUTPUT_DIR := "$(TMPDIR)/rustdoc-themes" all: - cp $(S)/src/librustdoc/html/static/css/themes/light.css $(TMPDIR)/test.css + awk '/Begin theme: light/ {in_theme=1;next} /End theme:/ {in_theme=0} { if (in_theme) print }' \ + < '$(S)/src/librustdoc/html/static/css/noscript.css' > '$(TMPDIR)/test.css' $(RUSTDOC) -o $(OUTPUT_DIR) foo.rs --theme $(TMPDIR)/test.css $(HTMLDOCCK) $(OUTPUT_DIR) foo.rs diff --git a/tests/rustdoc-gui/search-corrections.goml b/tests/rustdoc-gui/search-corrections.goml index 5d1b83b35c5..aeb3c9b31a3 100644 --- a/tests/rustdoc-gui/search-corrections.goml +++ b/tests/rustdoc-gui/search-corrections.goml @@ -54,3 +54,53 @@ assert-text: ( ".search-corrections", "Type \"notablestructwithlongnamr\" not found. Showing results for closest type name \"notablestructwithlongname\" instead." ) + +// Now, generic correction +go-to: "file://" + |DOC_PATH| + "/test_docs/index.html" +// Intentionally wrong spelling of "NotableStructWithLongName" +write: (".search-input", "NotableStructWithLongNamr, NotableStructWithLongNamr") +// To be SURE that the search will be run. +press-key: 'Enter' +// Waiting for the search results to appear... +wait-for: "#search-tabs" + +assert-css: (".search-corrections", { + "display": "block" +}) +assert-text: ( + ".search-corrections", + "Type \"notablestructwithlongnamr\" not found and used as generic parameter. Consider searching for \"notablestructwithlongname\" instead." +) + +// Now, generic correction plus error +go-to: "file://" + |DOC_PATH| + "/test_docs/index.html" +// Intentionally wrong spelling of "NotableStructWithLongName" +write: (".search-input", "Foo<NotableStructWithLongNamr>,y") +// To be SURE that the search will be run. +press-key: 'Enter' +// Waiting for the search results to appear... +wait-for: "#search-tabs" + +assert-css: (".search-corrections", { + "display": "block" +}) +assert-text: ( + ".search-corrections", + "Type \"notablestructwithlongnamr\" not found and used as generic parameter. Consider searching for \"notablestructwithlongname\" instead." +) + +go-to: "file://" + |DOC_PATH| + "/test_docs/index.html" +// Intentionally wrong spelling of "NotableStructWithLongName" +write: (".search-input", "generic:NotableStructWithLongNamr<x>,y") +// To be SURE that the search will be run. +press-key: 'Enter' +// Waiting for the search results to appear... +wait-for: "#search-tabs" + +assert-css: (".error", { + "display": "block" +}) +assert-text: ( + ".error", + "Query parser error: \"Generic type parameter notablestructwithlongnamr does not accept generic parameters\"." +) diff --git a/tests/rustdoc-gui/search-result-color.goml b/tests/rustdoc-gui/search-result-color.goml index f9f81c5ba04..44677dfbfef 100644 --- a/tests/rustdoc-gui/search-result-color.goml +++ b/tests/rustdoc-gui/search-result-color.goml @@ -151,7 +151,7 @@ assert-css: ( ) assert-css: ( "//*[@class='result-name']//*[text()='test_docs::']/ancestor::a", - {"color": "#fff", "background-color": "rgb(60, 60, 60)"}, + {"color": "#fff", "background-color": "#3c3c3c"}, ) // Dark theme diff --git a/tests/rustdoc-gui/sidebar-source-code.goml b/tests/rustdoc-gui/sidebar-source-code.goml index 69c589741cb..92b9045b734 100644 --- a/tests/rustdoc-gui/sidebar-source-code.goml +++ b/tests/rustdoc-gui/sidebar-source-code.goml @@ -73,7 +73,7 @@ assert: "//*[@class='dir-entry' and @open]/*[text()='sub_mod']" // Only "another_folder" should be "open" in "lib2". assert: "//*[@class='dir-entry' and not(@open)]/*[text()='another_mod']" // All other trees should be collapsed. -assert-count: ("//*[@id='src-sidebar']/details[not(text()='lib2') and not(@open)]", 9) +assert-count: ("//*[@id='src-sidebar']/details[not(text()='lib2') and not(@open)]", 10) // We now switch to mobile mode. set-window-size: (600, 600) diff --git a/tests/rustdoc-gui/src/theme_css/Cargo.lock b/tests/rustdoc-gui/src/theme_css/Cargo.lock new file mode 100644 index 00000000000..7ad6737a4d0 --- /dev/null +++ b/tests/rustdoc-gui/src/theme_css/Cargo.lock @@ -0,0 +1,7 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "theme_css" +version = "0.1.0" diff --git a/tests/rustdoc-gui/src/theme_css/Cargo.toml b/tests/rustdoc-gui/src/theme_css/Cargo.toml new file mode 100644 index 00000000000..798e64f9309 --- /dev/null +++ b/tests/rustdoc-gui/src/theme_css/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "theme_css" +version = "0.1.0" +edition = "2018" + +[lib] +path = "lib.rs" diff --git a/tests/rustdoc-gui/src/theme_css/custom-theme.css b/tests/rustdoc-gui/src/theme_css/custom-theme.css new file mode 100644 index 00000000000..260ef87f6ea --- /dev/null +++ b/tests/rustdoc-gui/src/theme_css/custom-theme.css @@ -0,0 +1,99 @@ +:root { + --main-background-color: red; + --main-color: black; + --settings-input-color: #2196f3; + --settings-input-border-color: #717171; + --settings-button-color: #000; + --settings-button-border-focus: #717171; + --sidebar-background-color: #f5f5f5; + --sidebar-background-color-hover: #e0e0e0; + --code-block-background-color: #f5f5f5; + --scrollbar-track-background-color: #dcdcdc; + --scrollbar-thumb-background-color: rgba(36, 37, 39, 0.6); + --scrollbar-color: rgba(36, 37, 39, 0.6) #d9d9d9; + --headings-border-bottom-color: #ddd; + --border-color: #e0e0e0; + --button-background-color: #fff; + --right-side-color: grey; + --code-attribute-color: #999; + --toggles-color: #999; + --toggle-filter: none; + --search-input-focused-border-color: #66afe9; + --copy-path-button-color: #999; + --copy-path-img-filter: invert(50%); + --copy-path-img-hover-filter: invert(35%); + --codeblock-error-hover-color: rgb(255, 0, 0); + --codeblock-error-color: rgba(255, 0, 0, .5); + --codeblock-ignore-hover-color: rgb(255, 142, 0); + --codeblock-ignore-color: rgba(255, 142, 0, .6); + --warning-border-color: #ff8e00; + --type-link-color: #ad378a; + --trait-link-color: #6e4fc9; + --assoc-item-link-color: #3873ad; + --function-link-color: #ad7c37; + --macro-link-color: #068000; + --keyword-link-color: #3873ad; + --mod-link-color: #3873ad; + --link-color: #3873ad; + --sidebar-link-color: #356da4; + --sidebar-current-link-background-color: #fff; + --search-result-link-focus-background-color: #ccc; + --search-result-border-color: #aaa3; + --search-color: #000; + --search-error-code-background-color: #d0cccc; + --search-results-alias-color: #000; + --search-results-grey-color: #999; + --search-tab-title-count-color: #888; + --search-tab-button-not-selected-border-top-color: #e6e6e6; + --search-tab-button-not-selected-background: #e6e6e6; + --search-tab-button-selected-border-top-color: #0089ff; + --search-tab-button-selected-background: #fff; + --stab-background-color: #fff5d6; + --stab-code-color: #000; + --code-highlight-kw-color: #8959a8; + --code-highlight-kw-2-color: #4271ae; + --code-highlight-lifetime-color: #b76514; + --code-highlight-prelude-color: #4271ae; + --code-highlight-prelude-val-color: #c82829; + --code-highlight-number-color: #718c00; + --code-highlight-string-color: #718c00; + --code-highlight-literal-color: #c82829; + --code-highlight-attribute-color: #c82829; + --code-highlight-self-color: #c82829; + --code-highlight-macro-color: #3e999f; + --code-highlight-question-mark-color: #ff9011; + --code-highlight-comment-color: #8e908c; + --code-highlight-doc-comment-color: #4d4d4c; + --src-line-numbers-span-color: #c67e2d; + --src-line-number-highlighted-background-color: #fdffd3; + --test-arrow-color: #f5f5f5; + --test-arrow-background-color: rgba(78, 139, 202, 0.2); + --test-arrow-hover-color: #f5f5f5; + --test-arrow-hover-background-color: rgb(78, 139, 202); + --target-background-color: #fdffd3; + --target-border-color: #ad7c37; + --kbd-color: #000; + --kbd-background: #fafbfc; + --kbd-box-shadow-color: #c6cbd1; + --rust-logo-filter: initial; + /* match border-color; uses https://codepen.io/sosuke/pen/Pjoqqp */ + --crate-search-div-filter: invert(100%) sepia(0%) saturate(4223%) hue-rotate(289deg) + brightness(114%) contrast(76%); + --crate-search-div-hover-filter: invert(44%) sepia(18%) saturate(23%) hue-rotate(317deg) + brightness(96%) contrast(93%); + --crate-search-hover-border: #717171; + --src-sidebar-background-selected: #fff; + --src-sidebar-background-hover: #e0e0e0; + --table-alt-row-background-color: #f5f5f5; + --codeblock-link-background: #eee; + --scrape-example-toggle-line-background: #ccc; + --scrape-example-toggle-line-hover-background: #999; + --scrape-example-code-line-highlight: #fcffd6; + --scrape-example-code-line-highlight-focus: #f6fdb0; + --scrape-example-help-border-color: #555; + --scrape-example-help-color: #333; + --scrape-example-help-hover-border-color: #000; + --scrape-example-help-hover-color: #000; + --scrape-example-code-wrapper-background-start: rgba(255, 255, 255, 1); + --scrape-example-code-wrapper-background-end: rgba(255, 255, 255, 0); +} diff --git a/tests/rustdoc-gui/src/theme_css/lib.rs b/tests/rustdoc-gui/src/theme_css/lib.rs new file mode 100644 index 00000000000..e9f3265fa6b --- /dev/null +++ b/tests/rustdoc-gui/src/theme_css/lib.rs @@ -0,0 +1,2 @@ +// compile-flags: --theme custom-theme.css +//! <div class="custom-text">custom text</div> diff --git a/tests/rustdoc-gui/theme-change.goml b/tests/rustdoc-gui/theme-change.goml index e4b031b735e..fdaf9d6289a 100644 --- a/tests/rustdoc-gui/theme-change.goml +++ b/tests/rustdoc-gui/theme-change.goml @@ -65,3 +65,36 @@ assert-local-storage: { "rustdoc-theme": "light" } reload: wait-for: "#settings" assert: "#preferred-light-theme.setting-line.hidden" + +// Ensures that the custom theme feature is working as expected. +go-to: "file://" + |DOC_PATH| + "/theme_css/index.html" +set-local-storage: {"rustdoc-use-system-theme": "false", "rustdoc-theme": "dark"} +reload: + +store-value: (background_light, "white") +store-value: (background_dark, "#353535") +store-value: (background_ayu, "#0f1419") +store-value: (background_custom_theme, "red") + +click: "#settings-menu" +wait-for: "#theme-ayu" +click: "#theme-ayu" +// should be the ayu theme so let's check the color. +wait-for-css: ("body", { "background-color": |background_ayu| }) +assert-local-storage: { "rustdoc-theme": "ayu" } +assert-text: (".custom-text", "custom text") +click: "#theme-light" +// should be the light theme so let's check the color. +wait-for-css: ("body", { "background-color": |background_light| }) +assert-local-storage: { "rustdoc-theme": "light" } +assert-text: (".custom-text", "custom text") +click: "#theme-dark" +// Should be the dark theme so let's check the color. +wait-for-css: ("body", { "background-color": |background_dark| }) +assert-local-storage: { "rustdoc-theme": "dark" } +assert-text: (".custom-text", "custom text") +click: "#theme-custom-theme" +// Should be the custom theme so let's check the color. +wait-for-css: ("body", { "background-color": |background_custom_theme| }) +assert-local-storage: { "rustdoc-theme": "custom-theme" } +assert-text: (".custom-text", "custom text") diff --git a/tests/rustdoc-js-std/option-type-signatures.js b/tests/rustdoc-js-std/option-type-signatures.js index 25997850661..e154fa707ab 100644 --- a/tests/rustdoc-js-std/option-type-signatures.js +++ b/tests/rustdoc-js-std/option-type-signatures.js @@ -1,3 +1,7 @@ +// ignore-order + +const FILTER_CRATE = "std"; + const EXPECTED = [ { 'query': 'option, fnonce -> option', @@ -19,4 +23,62 @@ const EXPECTED = [ { 'path': 'std::option::Option', 'name': 'as_mut_slice' }, ], }, + { + 'query': 'option<t>, option<t> -> option<t>', + 'others': [ + { 'path': 'std::option::Option', 'name': 'or' }, + { 'path': 'std::option::Option', 'name': 'xor' }, + ], + }, + { + 'query': 'option<t>, option<u> -> option<u>', + 'others': [ + { 'path': 'std::option::Option', 'name': 'and' }, + { 'path': 'std::option::Option', 'name': 'zip' }, + ], + }, + { + 'query': 'option<t>, option<u> -> option<t>', + 'others': [ + { 'path': 'std::option::Option', 'name': 'and' }, + { 'path': 'std::option::Option', 'name': 'zip' }, + ], + }, + { + 'query': 'option<t>, option<u> -> option<t, u>', + 'others': [ + { 'path': 'std::option::Option', 'name': 'zip' }, + ], + }, + { + 'query': 'option<t>, e -> result<t, e>', + 'others': [ + { 'path': 'std::option::Option', 'name': 'ok_or' }, + { 'path': 'std::result::Result', 'name': 'transpose' }, + ], + }, + { + 'query': 'result<option<t>, e> -> option<result<t, e>>', + 'others': [ + { 'path': 'std::result::Result', 'name': 'transpose' }, + ], + }, + { + 'query': 'option<t>, option<t> -> bool', + 'others': [ + { 'path': 'std::option::Option', 'name': 'eq' }, + ], + }, + { + 'query': 'option<option<t>> -> option<t>', + 'others': [ + { 'path': 'std::option::Option', 'name': 'flatten' }, + ], + }, + { + 'query': 'option<t>', + 'returned': [ + { 'path': 'std::result::Result', 'name': 'ok' }, + ], + }, ]; diff --git a/tests/rustdoc-js-std/vec-type-signatures.js b/tests/rustdoc-js-std/vec-type-signatures.js new file mode 100644 index 00000000000..18cf9d6efd0 --- /dev/null +++ b/tests/rustdoc-js-std/vec-type-signatures.js @@ -0,0 +1,22 @@ +// ignore-order + +const FILTER_CRATE = "std"; + +const EXPECTED = [ + { + 'query': 'vec::intoiter<T> -> [T]', + 'others': [ + { 'path': 'std::vec::IntoIter', 'name': 'as_slice' }, + { 'path': 'std::vec::IntoIter', 'name': 'as_mut_slice' }, + { 'path': 'std::vec::IntoIter', 'name': 'next_chunk' }, + ], + }, + { + 'query': 'vec::intoiter<T> -> []', + 'others': [ + { 'path': 'std::vec::IntoIter', 'name': 'as_slice' }, + { 'path': 'std::vec::IntoIter', 'name': 'as_mut_slice' }, + { 'path': 'std::vec::IntoIter', 'name': 'next_chunk' }, + ], + }, +]; diff --git a/tests/rustdoc-js/generics-match-ambiguity.js b/tests/rustdoc-js/generics-match-ambiguity.js index a9932a16ca3..edce4268c5a 100644 --- a/tests/rustdoc-js/generics-match-ambiguity.js +++ b/tests/rustdoc-js/generics-match-ambiguity.js @@ -79,6 +79,7 @@ const EXPECTED = [ { 'path': 'generics_match_ambiguity', 'name': 'baac' }, { 'path': 'generics_match_ambiguity', 'name': 'baaf' }, { 'path': 'generics_match_ambiguity', 'name': 'baag' }, + { 'path': 'generics_match_ambiguity', 'name': 'baah' }, ], }, { diff --git a/tests/rustdoc-js/generics-trait.js b/tests/rustdoc-js/generics-trait.js index 4ccfb8f4e4d..a71393b5e05 100644 --- a/tests/rustdoc-js/generics-trait.js +++ b/tests/rustdoc-js/generics-trait.js @@ -12,12 +12,16 @@ const EXPECTED = [ ], }, { - 'query': 'Result<SomeTraiz>', - 'correction': null, + 'query': 'Resulx<SomeTrait>', 'in_args': [], 'returned': [], }, { + 'query': 'Result<SomeTraiz>', + 'proposeCorrectionFrom': 'SomeTraiz', + 'proposeCorrectionTo': 'SomeTrait', + }, + { 'query': 'OtherThingxxxxxxxx', 'correction': null, 'in_args': [ diff --git a/tests/rustdoc-js/generics-unbox.js b/tests/rustdoc-js/generics-unbox.js new file mode 100644 index 00000000000..9cdfc7ac8b6 --- /dev/null +++ b/tests/rustdoc-js/generics-unbox.js @@ -0,0 +1,38 @@ +// exact-check + +const EXPECTED = [ + { + 'query': 'Inside<T> -> Out1<T>', + 'others': [ + { 'path': 'generics_unbox', 'name': 'alpha' }, + ], + }, + { + 'query': 'Inside<T> -> Out3<T>', + 'others': [ + { 'path': 'generics_unbox', 'name': 'beta' }, + { 'path': 'generics_unbox', 'name': 'gamma' }, + ], + }, + { + 'query': 'Inside<T> -> Out4<T>', + 'others': [ + { 'path': 'generics_unbox', 'name': 'beta' }, + { 'path': 'generics_unbox', 'name': 'gamma' }, + ], + }, + { + 'query': 'Inside<T> -> Out3<U, T>', + 'others': [ + { 'path': 'generics_unbox', 'name': 'beta' }, + { 'path': 'generics_unbox', 'name': 'gamma' }, + ], + }, + { + 'query': 'Inside<T> -> Out4<U, T>', + 'others': [ + { 'path': 'generics_unbox', 'name': 'beta' }, + { 'path': 'generics_unbox', 'name': 'gamma' }, + ], + }, +]; diff --git a/tests/rustdoc-js/generics-unbox.rs b/tests/rustdoc-js/generics-unbox.rs new file mode 100644 index 00000000000..bef34f891e9 --- /dev/null +++ b/tests/rustdoc-js/generics-unbox.rs @@ -0,0 +1,36 @@ +pub struct Out<A, B = ()> { + a: A, + b: B, +} + +pub struct Out1<A, const N: usize> { + a: [A; N], +} + +pub struct Out2<A, const N: usize> { + a: [A; N], +} + +pub struct Out3<A, B> { + a: A, + b: B, +} + +pub struct Out4<A, B> { + a: A, + b: B, +} + +pub struct Inside<T>(T); + +pub fn alpha<const N: usize, T>(_: Inside<T>) -> Out<Out1<T, N>, Out2<T, N>> { + loop {} +} + +pub fn beta<T, U>(_: Inside<T>) -> Out<Out3<T, U>, Out4<U, T>> { + loop {} +} + +pub fn gamma<T, U>(_: Inside<T>) -> Out<Out3<U, T>, Out4<T, U>> { + loop {} +} diff --git a/tests/rustdoc-js/type-parameters.js b/tests/rustdoc-js/type-parameters.js new file mode 100644 index 00000000000..e695f189bb6 --- /dev/null +++ b/tests/rustdoc-js/type-parameters.js @@ -0,0 +1,87 @@ +// exact-check +// ignore-order + +const EXPECTED = [ + { + query: '-> trait:Some', + others: [ + { path: 'foo', name: 'alef' }, + { path: 'foo', name: 'alpha' }, + ], + }, + { + query: '-> generic:T', + others: [ + { path: 'foo', name: 'bet' }, + { path: 'foo', name: 'alef' }, + { path: 'foo', name: 'beta' }, + ], + }, + { + query: 'A -> B', + others: [ + { path: 'foo', name: 'bet' }, + ], + }, + { + query: 'A -> A', + others: [ + { path: 'foo', name: 'beta' }, + ], + }, + { + query: 'A, A', + others: [ + { path: 'foo', name: 'alternate' }, + ], + }, + { + query: 'A, B', + others: [ + { path: 'foo', name: 'other' }, + ], + }, + { + query: 'Other, Other', + others: [ + { path: 'foo', name: 'other' }, + { path: 'foo', name: 'alternate' }, + ], + }, + { + query: 'generic:T', + in_args: [ + { path: 'foo', name: 'bet' }, + { path: 'foo', name: 'beta' }, + { path: 'foo', name: 'other' }, + { path: 'foo', name: 'alternate' }, + ], + }, + { + query: 'generic:Other', + in_args: [ + { path: 'foo', name: 'bet' }, + { path: 'foo', name: 'beta' }, + { path: 'foo', name: 'other' }, + { path: 'foo', name: 'alternate' }, + ], + }, + { + query: 'trait:Other', + in_args: [ + { path: 'foo', name: 'other' }, + { path: 'foo', name: 'alternate' }, + ], + }, + { + query: 'Other', + in_args: [ + { path: 'foo', name: 'other' }, + { path: 'foo', name: 'alternate' }, + ], + }, + { + query: 'trait:T', + in_args: [], + }, +]; diff --git a/tests/rustdoc-js/type-parameters.rs b/tests/rustdoc-js/type-parameters.rs new file mode 100644 index 00000000000..cda5e26171f --- /dev/null +++ b/tests/rustdoc-js/type-parameters.rs @@ -0,0 +1,15 @@ +#![crate_name="foo"] + +pub trait Some {} +impl Some for () {} +pub trait Other {} +impl Other for () {} + +pub fn alef<T: Some>() -> T { loop {} } +pub fn alpha() -> impl Some { } + +pub fn bet<T, U>(t: T) -> U { loop {} } +pub fn beta<T>(t: T) -> T {} + +pub fn other<T: Other, U: Other>(t: T, u: U) { loop {} } +pub fn alternate<T: Other>(t: T, u: T) { loop {} } diff --git a/tests/rustdoc-ui/custom_code_classes_in_docs-warning.rs b/tests/rustdoc-ui/custom_code_classes_in_docs-warning.rs new file mode 100644 index 00000000000..5398d5833c7 --- /dev/null +++ b/tests/rustdoc-ui/custom_code_classes_in_docs-warning.rs @@ -0,0 +1,83 @@ +// This test ensures that warnings are working as expected for "custom_code_classes_in_docs" +// feature. + +#![feature(custom_code_classes_in_docs)] +#![deny(warnings)] +#![feature(no_core)] +#![no_core] + +/// ```{. } +/// main; +/// ``` +//~^^^ ERROR unexpected ` ` character after `.` +pub fn foo() {} + +/// ```{class= a} +/// main; +/// ``` +//~^^^ ERROR unexpected ` ` character after `=` +pub fn foo2() {} + +/// ```{#id} +/// main; +/// ``` +//~^^^ ERROR unexpected character `#` +pub fn foo3() {} + +/// ```{{ +/// main; +/// ``` +//~^^^ ERROR unexpected character `{` +pub fn foo4() {} + +/// ```} +/// main; +/// ``` +//~^^^ ERROR unexpected character `}` +pub fn foo5() {} + +/// ```) +/// main; +/// ``` +//~^^^ ERROR unexpected character `)` +pub fn foo6() {} + +/// ```{class=} +/// main; +/// ``` +//~^^^ ERROR unexpected `}` character after `=` +pub fn foo7() {} + +/// ```( +/// main; +/// ``` +//~^^^ ERROR unclosed comment: missing `)` at the end +pub fn foo8() {} + +/// ```{class=one=two} +/// main; +/// ``` +//~^^^ ERROR unexpected `=` character +pub fn foo9() {} + +/// ```{.one.two} +/// main; +/// ``` +pub fn foo10() {} + +/// ```{class=(one} +/// main; +/// ``` +//~^^^ ERROR unexpected `(` character after `=` +pub fn foo11() {} + +/// ```{class=one.two} +/// main; +/// ``` +pub fn foo12() {} + +/// ```{(comment)} +/// main; +/// ``` +//~^^^ ERROR unexpected character `(` +pub fn foo13() {} diff --git a/tests/rustdoc-ui/custom_code_classes_in_docs-warning.stderr b/tests/rustdoc-ui/custom_code_classes_in_docs-warning.stderr new file mode 100644 index 00000000000..14b4b3bab3f --- /dev/null +++ b/tests/rustdoc-ui/custom_code_classes_in_docs-warning.stderr @@ -0,0 +1,97 @@ +error: unexpected ` ` character after `.` + --> $DIR/custom_code_classes_in_docs-warning.rs:9:1 + | +LL | / /// ```{. } +LL | | /// main; +LL | | /// ``` + | |_______^ + | +note: the lint level is defined here + --> $DIR/custom_code_classes_in_docs-warning.rs:5:9 + | +LL | #![deny(warnings)] + | ^^^^^^^^ + = note: `#[deny(rustdoc::invalid_codeblock_attributes)]` implied by `#[deny(warnings)]` + +error: unexpected ` ` character after `=` + --> $DIR/custom_code_classes_in_docs-warning.rs:15:1 + | +LL | / /// ```{class= a} +LL | | /// main; +LL | | /// ``` + | |_______^ + +error: unexpected character `#` + --> $DIR/custom_code_classes_in_docs-warning.rs:21:1 + | +LL | / /// ```{#id} +LL | | /// main; +LL | | /// ``` + | |_______^ + +error: unexpected character `{` + --> $DIR/custom_code_classes_in_docs-warning.rs:27:1 + | +LL | / /// ```{{ +LL | | /// main; +LL | | /// ``` + | |_______^ + +error: unexpected character `}` + --> $DIR/custom_code_classes_in_docs-warning.rs:33:1 + | +LL | / /// ```} +LL | | /// main; +LL | | /// ``` + | |_______^ + +error: unexpected character `)` + --> $DIR/custom_code_classes_in_docs-warning.rs:39:1 + | +LL | / /// ```) +LL | | /// main; +LL | | /// ``` + | |_______^ + +error: unexpected `}` character after `=` + --> $DIR/custom_code_classes_in_docs-warning.rs:45:1 + | +LL | / /// ```{class=} +LL | | /// main; +LL | | /// ``` + | |_______^ + +error: unclosed comment: missing `)` at the end + --> $DIR/custom_code_classes_in_docs-warning.rs:51:1 + | +LL | / /// ```( +LL | | /// main; +LL | | /// ``` + | |_______^ + +error: unexpected `=` character + --> $DIR/custom_code_classes_in_docs-warning.rs:57:1 + | +LL | / /// ```{class=one=two} +LL | | /// main; +LL | | /// ``` + | |_______^ + +error: unexpected `(` character after `=` + --> $DIR/custom_code_classes_in_docs-warning.rs:68:1 + | +LL | / /// ```{class=(one} +LL | | /// main; +LL | | /// ``` + | |_______^ + +error: unexpected character `(` + --> $DIR/custom_code_classes_in_docs-warning.rs:79:1 + | +LL | / /// ```{(comment)} +LL | | /// main; +LL | | /// ``` + | |_______^ + +error: aborting due to 11 previous errors + diff --git a/tests/rustdoc-ui/custom_code_classes_in_docs-warning3.rs b/tests/rustdoc-ui/custom_code_classes_in_docs-warning3.rs new file mode 100644 index 00000000000..57d9038cb0c --- /dev/null +++ b/tests/rustdoc-ui/custom_code_classes_in_docs-warning3.rs @@ -0,0 +1,17 @@ +// This test ensures that warnings are working as expected for "custom_code_classes_in_docs" +// feature. + +#![feature(custom_code_classes_in_docs)] +#![deny(warnings)] +#![feature(no_core)] +#![no_core] + +/// ```{class="} +/// main; +/// ``` +//~^^^ ERROR unclosed quote string +//~| ERROR unclosed quote string +/// ```" +/// main; +/// ``` +pub fn foo() {} diff --git a/tests/rustdoc-ui/custom_code_classes_in_docs-warning3.stderr b/tests/rustdoc-ui/custom_code_classes_in_docs-warning3.stderr new file mode 100644 index 00000000000..4f2ded78c29 --- /dev/null +++ b/tests/rustdoc-ui/custom_code_classes_in_docs-warning3.stderr @@ -0,0 +1,33 @@ +error: unclosed quote string `"` + --> $DIR/custom_code_classes_in_docs-warning3.rs:9:1 + | +LL | / /// ```{class="} +LL | | /// main; +LL | | /// ``` +LL | | +... | +LL | | /// main; +LL | | /// ``` + | |_______^ + | +note: the lint level is defined here + --> $DIR/custom_code_classes_in_docs-warning3.rs:5:9 + | +LL | #![deny(warnings)] + | ^^^^^^^^ + = note: `#[deny(rustdoc::invalid_codeblock_attributes)]` implied by `#[deny(warnings)]` + +error: unclosed quote string `"` + --> $DIR/custom_code_classes_in_docs-warning3.rs:9:1 + | +LL | / /// ```{class="} +LL | | /// main; +LL | | /// ``` +LL | | +... | +LL | | /// main; +LL | | /// ``` + | |_______^ + +error: aborting due to 2 previous errors + diff --git a/tests/rustdoc-ui/feature-gate-custom_code_classes_in_docs.rs b/tests/rustdoc-ui/feature-gate-custom_code_classes_in_docs.rs new file mode 100644 index 00000000000..99263a944f8 --- /dev/null +++ b/tests/rustdoc-ui/feature-gate-custom_code_classes_in_docs.rs @@ -0,0 +1,15 @@ +// check-pass + +/// ```{class=language-c} +/// int main(void) { return 0; } +/// ``` +//~^^^ WARNING custom classes in code blocks will change behaviour +//~| NOTE found these custom classes: class=language-c +//~| NOTE see issue #79483 <https://github.com/rust-lang/rust/issues/79483> +//~| HELP add `#![feature(custom_code_classes_in_docs)]` to the crate attributes to enable +pub struct Bar; + +/// ```ASN.1 +/// int main(void) { return 0; } +/// ``` +pub struct Bar2; diff --git a/tests/rustdoc-ui/feature-gate-custom_code_classes_in_docs.stderr b/tests/rustdoc-ui/feature-gate-custom_code_classes_in_docs.stderr new file mode 100644 index 00000000000..1a2360d9b30 --- /dev/null +++ b/tests/rustdoc-ui/feature-gate-custom_code_classes_in_docs.stderr @@ -0,0 +1,14 @@ +warning: custom classes in code blocks will change behaviour + --> $DIR/feature-gate-custom_code_classes_in_docs.rs:3:1 + | +LL | / /// ```{class=language-c} +LL | | /// int main(void) { return 0; } +LL | | /// ``` + | |_______^ + | + = note: see issue #79483 <https://github.com/rust-lang/rust/issues/79483> for more information + = help: add `#![feature(custom_code_classes_in_docs)]` to the crate attributes to enable + = note: found these custom classes: class=language-c + +warning: 1 warning emitted + diff --git a/tests/rustdoc-ui/issues/issue-91713.stdout b/tests/rustdoc-ui/issues/issue-91713.stdout index 16783524363..bbea7e5c212 100644 --- a/tests/rustdoc-ui/issues/issue-91713.stdout +++ b/tests/rustdoc-ui/issues/issue-91713.stdout @@ -1,4 +1,5 @@ Available passes for running rustdoc: +check-custom-code-classes - check for custom code classes without the feature-gate enabled check_doc_test_visibility - run various visibility-related lints on doctests strip-hidden - strips all `#[doc(hidden)]` items from the output strip-private - strips all private items from a crate which cannot be seen externally, implies strip-priv-imports @@ -10,6 +11,7 @@ calculate-doc-coverage - counts the number of items with and without documentati run-lints - runs some of rustdoc's lints Default passes for rustdoc: +check-custom-code-classes collect-trait-impls check_doc_test_visibility strip-hidden (when not --document-hidden-items) diff --git a/tests/rustdoc/custom_code_classes.rs b/tests/rustdoc/custom_code_classes.rs new file mode 100644 index 00000000000..cd20d8b7d6c --- /dev/null +++ b/tests/rustdoc/custom_code_classes.rs @@ -0,0 +1,28 @@ +// Test for `custom_code_classes_in_docs` feature. + +#![feature(custom_code_classes_in_docs)] +#![crate_name = "foo"] +#![feature(no_core)] +#![no_core] + +// @has 'foo/struct.Bar.html' +// @has - '//*[@id="main-content"]//pre[@class="language-whatever hoho-c"]' 'main;' +// @has - '//*[@id="main-content"]//pre[@class="language-whatever2 haha-c"]' 'main;' +// @has - '//*[@id="main-content"]//pre[@class="language-whatever4 huhu-c"]' 'main;' + +/// ```{class=hoho-c},whatever +/// main; +/// ``` +/// +/// Testing multiple kinds of orders. +/// +/// ```whatever2 {class=haha-c} +/// main; +/// ``` +/// +/// Testing with multiple "unknown". Only the first should be used. +/// +/// ```whatever4,{.huhu-c} whatever5 +/// main; +/// ``` +pub struct Bar; diff --git a/tests/rustdoc/issue-32077-type-alias-impls.rs b/tests/rustdoc/issue-32077-type-alias-impls.rs index 26778c67c24..ac486c36ad0 100644 --- a/tests/rustdoc/issue-32077-type-alias-impls.rs +++ b/tests/rustdoc/issue-32077-type-alias-impls.rs @@ -19,6 +19,8 @@ impl<T> Foo for GenericStruct<T> {} impl Bar for GenericStruct<u32> {} // @has 'foo/type.TypedefStruct.html' +// We check that "Aliased type" is also present as a title in the sidebar. +// @has - '//*[@class="sidebar-elems"]//h3/a[@href="#aliased-type"]' 'Aliased type' // We check that we have the implementation of the type alias itself. // @has - '//*[@id="impl-TypedefStruct"]/h3' 'impl TypedefStruct' // @has - '//*[@id="method.on_alias"]/h4' 'pub fn on_alias()' diff --git a/tests/ui-fulldeps/pprust-expr-roundtrip.rs b/tests/ui-fulldeps/pprust-expr-roundtrip.rs index ae375dfab90..541be7ebbc0 100644 --- a/tests/ui-fulldeps/pprust-expr-roundtrip.rs +++ b/tests/ui-fulldeps/pprust-expr-roundtrip.rs @@ -80,14 +80,20 @@ fn iter_exprs(depth: usize, f: &mut dyn FnMut(P<Expr>)) { let seg = PathSegment::from_ident(Ident::from_str("x")); iter_exprs(depth - 1, &mut |e| { g(ExprKind::MethodCall(Box::new(MethodCall { - seg: seg.clone(), receiver: e, args: thin_vec![make_x()], span: DUMMY_SP - })) - )}); + seg: seg.clone(), + receiver: e, + args: thin_vec![make_x()], + span: DUMMY_SP, + }))) + }); iter_exprs(depth - 1, &mut |e| { g(ExprKind::MethodCall(Box::new(MethodCall { - seg: seg.clone(), receiver: make_x(), args: thin_vec![e], span: DUMMY_SP - })) - )}); + seg: seg.clone(), + receiver: make_x(), + args: thin_vec![e], + span: DUMMY_SP, + }))) + }); } 2..=7 => { let op = Spanned { @@ -174,7 +180,7 @@ fn iter_exprs(depth: usize, f: &mut dyn FnMut(P<Expr>)) { 18 => { let pat = P(Pat { id: DUMMY_NODE_ID, kind: PatKind::Wild, span: DUMMY_SP, tokens: None }); - iter_exprs(depth - 1, &mut |e| g(ExprKind::Let(pat.clone(), e, DUMMY_SP))) + iter_exprs(depth - 1, &mut |e| g(ExprKind::Let(pat.clone(), e, DUMMY_SP, None))) } _ => panic!("bad counter value in iter_exprs"), } diff --git a/tests/ui-fulldeps/stable-mir/crate-info.rs b/tests/ui-fulldeps/stable-mir/crate-info.rs index d55eae86f07..a11720c4b55 100644 --- a/tests/ui-fulldeps/stable-mir/crate-info.rs +++ b/tests/ui-fulldeps/stable-mir/crate-info.rs @@ -154,6 +154,10 @@ fn test_stable_mir(tcx: TyCtxt<'_>) -> ControlFlow<()> { } } + let foo_const = get_item(tcx, &items, (DefKind::Const, "FOO")).unwrap(); + // Ensure we don't panic trying to get the body of a constant. + foo_const.body(); + ControlFlow::Continue(()) } @@ -191,6 +195,8 @@ fn generate_input(path: &str) -> std::io::Result<()> { write!( file, r#" + pub const FOO: u32 = 1 + 2; + fn generic<T, const U: usize>(t: T) -> [(); U] {{ _ = t; [(); U] diff --git a/tests/ui/abi/compatibility.rs b/tests/ui/abi/compatibility.rs index 86fb365507a..d4f42cdda97 100644 --- a/tests/ui/abi/compatibility.rs +++ b/tests/ui/abi/compatibility.rs @@ -1,15 +1,23 @@ // check-pass -#![feature(rustc_attrs, transparent_unions)] -#![allow(unused, improper_ctypes_definitions)] +#![feature(rustc_attrs, unsized_fn_params, transparent_unions)] +#![allow(unused, improper_ctypes_definitions, internal_features)] use std::marker::PhantomData; use std::mem::ManuallyDrop; use std::num::NonZeroI32; use std::ptr::NonNull; +// FIXME: a bunch of targets are broken in various ways. +// Hence there are `cfg` throughout this test to disable parts of it on those targets. +// sparc64: https://github.com/rust-lang/rust/issues/115336 +// mips64: https://github.com/rust-lang/rust/issues/115404 +// loongarch64: https://github.com/rust-lang/rust/issues/115509 + macro_rules! assert_abi_compatible { ($name:ident, $t1:ty, $t2:ty) => { mod $name { use super::*; + // Declaring a `type` doesn't even check well-formedness, so we also declare a function. + fn check_wf(_x: $t1, _y: $t2) {} // Test argument and return value, `Rust` and `C` ABIs. #[rustc_abi(assert_eq)] type TestRust = (fn($t1) -> $t1, fn($t2) -> $t2); @@ -23,7 +31,7 @@ macro_rules! assert_abi_compatible { struct Zst; #[repr(C)] -struct ReprC1<T>(T); +struct ReprC1<T: ?Sized>(T); #[repr(C)] struct ReprC2Int<T>(i32, T); #[repr(C)] @@ -72,14 +80,20 @@ test_abi_compatible!(fn_fn, fn(), fn(i32) -> i32); // Some further guarantees we will likely (have to) make. test_abi_compatible!(zst_unit, Zst, ()); +#[cfg(not(any(target_arch = "sparc64")))] test_abi_compatible!(zst_array, Zst, [u8; 0]); test_abi_compatible!(nonzero_int, NonZeroI32, i32); +// `DispatchFromDyn` relies on ABI compatibility. +// This is interesting since these types are not `repr(transparent)`. +test_abi_compatible!(rc, std::rc::Rc<i32>, *mut i32); +test_abi_compatible!(arc, std::sync::Arc<i32>, *mut i32); + // `repr(transparent)` compatibility. #[repr(transparent)] -struct Wrapper1<T>(T); +struct Wrapper1<T: ?Sized>(T); #[repr(transparent)] -struct Wrapper2<T>((), Zst, T); +struct Wrapper2<T: ?Sized>((), Zst, T); #[repr(transparent)] struct Wrapper3<T>(T, [u8; 0], PhantomData<u64>); #[repr(transparent)] @@ -95,6 +109,7 @@ macro_rules! test_transparent { test_abi_compatible!(wrap1, $t, Wrapper1<$t>); test_abi_compatible!(wrap2, $t, Wrapper2<$t>); test_abi_compatible!(wrap3, $t, Wrapper3<$t>); + #[cfg(not(target_arch = "loongarch64"))] test_abi_compatible!(wrap4, $t, WrapperUnion<$t>); } }; @@ -104,22 +119,50 @@ test_transparent!(simple, i32); test_transparent!(reference, &'static i32); test_transparent!(zst, Zst); test_transparent!(unit, ()); -test_transparent!(pair, (i32, f32)); // mixing in some floats since they often get special treatment -test_transparent!(triple, (i8, i16, f32)); // chosen to fit into 64bit -test_transparent!(tuple, (i32, f32, i64, f64)); -test_transparent!(empty_array, [u32; 0]); -test_transparent!(empty_1zst_array, [u8; 0]); -test_transparent!(small_array, [i32; 2]); // chosen to fit into 64bit -test_transparent!(large_array, [i32; 16]); test_transparent!(enum_, Option<i32>); test_transparent!(enum_niched, Option<&'static i32>); -// Pure-float types that are not ScalarPair seem to be tricky. -// FIXME: <https://github.com/rust-lang/rust/issues/115664> -#[cfg(not(any(target_arch = "arm", target_arch = "aarch64")))] -mod tricky { +#[cfg(not(any(target_arch = "mips64", target_arch = "sparc64")))] +mod tuples { use super::*; + // mixing in some floats since they often get special treatment + test_transparent!(pair, (i32, f32)); + // chosen to fit into 64bit + test_transparent!(triple, (i8, i16, f32)); + // Pure-float types that are not ScalarPair seem to be tricky. test_transparent!(triple_f32, (f32, f32, f32)); test_transparent!(triple_f64, (f64, f64, f64)); + // and also something that's larger than 2 pointers + test_transparent!(tuple, (i32, f32, i64, f64)); +} +// Some targets have special rules for arrays. +#[cfg(not(any(target_arch = "mips64", target_arch = "sparc64")))] +mod arrays { + use super::*; + test_transparent!(empty_array, [u32; 0]); + test_transparent!(empty_1zst_array, [u8; 0]); + test_transparent!(small_array, [i32; 2]); // chosen to fit into 64bit + test_transparent!(large_array, [i32; 16]); +} + +// Some tests with unsized types (not all wrappers are compatible with that). +macro_rules! test_transparent_unsized { + ($name:ident, $t:ty) => { + mod $name { + use super::*; + assert_abi_compatible!(wrap1, $t, Wrapper1<$t>); + assert_abi_compatible!(wrap1_reprc, ReprC1<$t>, ReprC1<Wrapper1<$t>>); + assert_abi_compatible!(wrap2, $t, Wrapper2<$t>); + assert_abi_compatible!(wrap2_reprc, ReprC1<$t>, ReprC1<Wrapper2<$t>>); + } + }; +} + +#[cfg(not(any(target_arch = "mips64", target_arch = "sparc64")))] +mod unsized_ { + use super::*; + test_transparent_unsized!(str_, str); + test_transparent_unsized!(slice, [u8]); + test_transparent_unsized!(dyn_trait, dyn std::any::Any); } // RFC 3391 <https://rust-lang.github.io/rfcs/3391-result_ffi_guarantees.html>. diff --git a/tests/ui/abi/debug.rs b/tests/ui/abi/debug.rs index ac37d7b6bff..77715ee4023 100644 --- a/tests/ui/abi/debug.rs +++ b/tests/ui/abi/debug.rs @@ -4,7 +4,6 @@ // normalize-stderr-test "(valid_range): 0\.\.=(4294967295|18446744073709551615)" -> "$1: $$FULL" // This pattern is prepared for when we account for alignment in the niche. // normalize-stderr-test "(valid_range): [1-9]\.\.=(429496729[0-9]|1844674407370955161[0-9])" -> "$1: $$NON_NULL" -// normalize-stderr-test "Leaf\(0x0*20\)" -> "Leaf(0x0...20)" // Some attributes are only computed for release builds: // compile-flags: -O #![feature(rustc_attrs)] diff --git a/tests/ui/abi/debug.stderr b/tests/ui/abi/debug.stderr index f56f5c525ab..00fc7d1ece1 100644 --- a/tests/ui/abi/debug.stderr +++ b/tests/ui/abi/debug.stderr @@ -87,7 +87,7 @@ error: fn_abi_of(test) = FnAbi { conv: Rust, can_unwind: $SOME_BOOL, } - --> $DIR/debug.rs:16:1 + --> $DIR/debug.rs:15:1 | LL | fn test(_x: u8) -> bool { true } | ^^^^^^^^^^^^^^^^^^^^^^^ @@ -181,7 +181,7 @@ error: fn_abi_of(TestFnPtr) = FnAbi { conv: Rust, can_unwind: $SOME_BOOL, } - --> $DIR/debug.rs:19:1 + --> $DIR/debug.rs:18:1 | LL | type TestFnPtr = fn(bool) -> u8; | ^^^^^^^^^^^^^^ @@ -190,7 +190,7 @@ error: fn_abi_of(test_generic) = FnAbi { args: [ ArgAbi { layout: TyAndLayout { - ty: *const T/#0, + ty: *const T, layout: Layout { size: $SOME_SIZE, align: AbiAndPrefAlign { @@ -257,13 +257,13 @@ error: fn_abi_of(test_generic) = FnAbi { conv: Rust, can_unwind: $SOME_BOOL, } - --> $DIR/debug.rs:22:1 + --> $DIR/debug.rs:21:1 | LL | fn test_generic<T>(_x: *const T) { } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: `#[rustc_abi]` can only be applied to function items, type aliases, and associated functions - --> $DIR/debug.rs:25:1 + --> $DIR/debug.rs:24:1 | LL | const C: () = (); | ^^^^^^^^^^^ @@ -409,7 +409,7 @@ error: ABIs are not compatible conv: Rust, can_unwind: $SOME_BOOL, } - --> $DIR/debug.rs:41:1 + --> $DIR/debug.rs:40:1 | LL | type TestAbiNe = (fn(u8), fn(u32)); | ^^^^^^^^^^^^^^ @@ -419,7 +419,7 @@ error: ABIs are not compatible args: [ ArgAbi { layout: TyAndLayout { - ty: [u8; Const { ty: usize, kind: Leaf(0x0...20) }], + ty: [u8; 32], layout: Layout { size: Size(32 bytes), align: AbiAndPrefAlign { @@ -450,7 +450,7 @@ error: ABIs are not compatible Align(1 bytes), ), }, - extra_attrs: None, + meta_attrs: None, on_stack: false, }, }, @@ -490,7 +490,7 @@ error: ABIs are not compatible args: [ ArgAbi { layout: TyAndLayout { - ty: [u32; Const { ty: usize, kind: Leaf(0x0...20) }], + ty: [u32; 32], layout: Layout { size: Size(128 bytes), align: AbiAndPrefAlign { @@ -521,7 +521,7 @@ error: ABIs are not compatible Align(4 bytes), ), }, - extra_attrs: None, + meta_attrs: None, on_stack: false, }, }, @@ -557,7 +557,7 @@ error: ABIs are not compatible conv: Rust, can_unwind: $SOME_BOOL, } - --> $DIR/debug.rs:44:1 + --> $DIR/debug.rs:43:1 | LL | type TestAbiNeLarger = (fn([u8; 32]), fn([u32; 32])); | ^^^^^^^^^^^^^^^^^^^^ @@ -700,7 +700,7 @@ error: ABIs are not compatible conv: Rust, can_unwind: $SOME_BOOL, } - --> $DIR/debug.rs:47:1 + --> $DIR/debug.rs:46:1 | LL | type TestAbiNeFloat = (fn(f32), fn(u32)); | ^^^^^^^^^^^^^^^^^^^ @@ -846,13 +846,13 @@ error: ABIs are not compatible conv: Rust, can_unwind: $SOME_BOOL, } - --> $DIR/debug.rs:51:1 + --> $DIR/debug.rs:50:1 | LL | type TestAbiNeSign = (fn(i32), fn(u32)); | ^^^^^^^^^^^^^^^^^^ error[E0277]: the size for values of type `str` cannot be known at compilation time - --> $DIR/debug.rs:54:46 + --> $DIR/debug.rs:53:46 | LL | type TestAbiEqNonsense = (fn((str, str)), fn((str, str))); | ^^^^^^^^^^ doesn't have a size known at compile-time @@ -861,7 +861,7 @@ LL | type TestAbiEqNonsense = (fn((str, str)), fn((str, str))); = note: only the last element of a tuple may have a dynamically sized type error: `#[rustc_abi]` can only be applied to function items, type aliases, and associated functions - --> $DIR/debug.rs:29:5 + --> $DIR/debug.rs:28:5 | LL | const C: () = (); | ^^^^^^^^^^^ @@ -870,7 +870,7 @@ error: fn_abi_of(assoc_test) = FnAbi { args: [ ArgAbi { layout: TyAndLayout { - ty: &ReErased Adt(S, []), + ty: &S, layout: Layout { size: $SOME_SIZE, align: AbiAndPrefAlign { @@ -949,7 +949,7 @@ error: fn_abi_of(assoc_test) = FnAbi { conv: Rust, can_unwind: $SOME_BOOL, } - --> $DIR/debug.rs:34:5 + --> $DIR/debug.rs:33:5 | LL | fn assoc_test(&self) { } | ^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/associated-consts/associated-const-array-len.stderr b/tests/ui/associated-consts/associated-const-array-len.stderr index 0e0dec35b53..e3db45810fd 100644 --- a/tests/ui/associated-consts/associated-const-array-len.stderr +++ b/tests/ui/associated-consts/associated-const-array-len.stderr @@ -3,6 +3,12 @@ error[E0277]: the trait bound `i32: Foo` is not satisfied | LL | const X: [i32; <i32 as Foo>::ID] = [0, 1, 2]; | ^^^ the trait `Foo` is not implemented for `i32` + | +help: this trait has no implementations, consider adding one + --> $DIR/associated-const-array-len.rs:1:1 + | +LL | trait Foo { + | ^^^^^^^^^ error: aborting due to previous error diff --git a/tests/ui/associated-consts/defaults-cyclic-fail.rs b/tests/ui/associated-consts/defaults-cyclic-fail.rs index a1c6840a0f1..9ef0003da17 100644 --- a/tests/ui/associated-consts/defaults-cyclic-fail.rs +++ b/tests/ui/associated-consts/defaults-cyclic-fail.rs @@ -3,7 +3,7 @@ // Cyclic assoc. const defaults don't error unless *used* trait Tr { const A: u8 = Self::B; - //~^ cycle detected when const-evaluating + checking `Tr::A` + //~^ cycle detected const B: u8 = Self::A; } diff --git a/tests/ui/associated-consts/defaults-cyclic-fail.stderr b/tests/ui/associated-consts/defaults-cyclic-fail.stderr index ebdb76e4286..e29c32f5dfd 100644 --- a/tests/ui/associated-consts/defaults-cyclic-fail.stderr +++ b/tests/ui/associated-consts/defaults-cyclic-fail.stderr @@ -1,15 +1,25 @@ -error[E0391]: cycle detected when const-evaluating + checking `Tr::A` +error[E0391]: cycle detected when simplifying constant for the type system `Tr::A` + --> $DIR/defaults-cyclic-fail.rs:5:5 + | +LL | const A: u8 = Self::B; + | ^^^^^^^^^^^ + | +note: ...which requires const-evaluating + checking `Tr::A`... --> $DIR/defaults-cyclic-fail.rs:5:19 | LL | const A: u8 = Self::B; | ^^^^^^^ +note: ...which requires simplifying constant for the type system `Tr::B`... + --> $DIR/defaults-cyclic-fail.rs:8:5 | +LL | const B: u8 = Self::A; + | ^^^^^^^^^^^ note: ...which requires const-evaluating + checking `Tr::B`... --> $DIR/defaults-cyclic-fail.rs:8:19 | LL | const B: u8 = Self::A; | ^^^^^^^ - = note: ...which again requires const-evaluating + checking `Tr::A`, completing the cycle + = note: ...which again requires simplifying constant for the type system `Tr::A`, completing the cycle note: cycle used when const-evaluating + checking `main::promoted[1]` --> $DIR/defaults-cyclic-fail.rs:16:16 | diff --git a/tests/ui/associated-consts/defaults-not-assumed-fail.stderr b/tests/ui/associated-consts/defaults-not-assumed-fail.stderr index 9b761b00691..d659912341a 100644 --- a/tests/ui/associated-consts/defaults-not-assumed-fail.stderr +++ b/tests/ui/associated-consts/defaults-not-assumed-fail.stderr @@ -4,13 +4,13 @@ error[E0080]: evaluation of `<() as Tr>::B` failed LL | const B: u8 = Self::A + 1; | ^^^^^^^^^^^ attempt to compute `u8::MAX + 1_u8`, which would overflow -note: erroneous constant used +note: erroneous constant encountered --> $DIR/defaults-not-assumed-fail.rs:33:16 | LL | assert_eq!(<() as Tr>::B, 0); // causes the error above | ^^^^^^^^^^^^^ -note: erroneous constant used +note: erroneous constant encountered --> $DIR/defaults-not-assumed-fail.rs:33:5 | LL | assert_eq!(<() as Tr>::B, 0); // causes the error above @@ -18,7 +18,7 @@ LL | assert_eq!(<() as Tr>::B, 0); // causes the error above | = note: this note originates in the macro `assert_eq` (in Nightly builds, run with -Z macro-backtrace for more info) -note: erroneous constant used +note: erroneous constant encountered --> $DIR/defaults-not-assumed-fail.rs:33:5 | LL | assert_eq!(<() as Tr>::B, 0); // causes the error above diff --git a/tests/ui/associated-consts/issue-105330.stderr b/tests/ui/associated-consts/issue-105330.stderr index e9fe3a5e514..927422fa8dc 100644 --- a/tests/ui/associated-consts/issue-105330.stderr +++ b/tests/ui/associated-consts/issue-105330.stderr @@ -51,6 +51,11 @@ error[E0277]: the trait bound `Demo: TraitWAssocConst` is not satisfied LL | foo::<Demo>()(); | ^^^^ the trait `TraitWAssocConst` is not implemented for `Demo` | +help: this trait has no implementations, consider adding one + --> $DIR/issue-105330.rs:1:1 + | +LL | pub trait TraitWAssocConst { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ note: required by a bound in `foo` --> $DIR/issue-105330.rs:11:11 | @@ -87,6 +92,11 @@ error[E0277]: the trait bound `Demo: TraitWAssocConst` is not satisfied LL | foo::<Demo>(); | ^^^^ the trait `TraitWAssocConst` is not implemented for `Demo` | +help: this trait has no implementations, consider adding one + --> $DIR/issue-105330.rs:1:1 + | +LL | pub trait TraitWAssocConst { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ note: required by a bound in `foo` --> $DIR/issue-105330.rs:11:11 | diff --git a/tests/ui/associated-consts/issue-24949-assoc-const-static-recursion-impl.stderr b/tests/ui/associated-consts/issue-24949-assoc-const-static-recursion-impl.stderr index 51bf0cb5e5c..4418fb7556b 100644 --- a/tests/ui/associated-consts/issue-24949-assoc-const-static-recursion-impl.stderr +++ b/tests/ui/associated-consts/issue-24949-assoc-const-static-recursion-impl.stderr @@ -4,7 +4,12 @@ error[E0391]: cycle detected when elaborating drops for `<impl at $DIR/issue-249 LL | const BAR: u32 = IMPL_REF_BAR; | ^^^^^^^^^^^^ | -note: ...which requires const-evaluating + checking `IMPL_REF_BAR`... +note: ...which requires simplifying constant for the type system `IMPL_REF_BAR`... + --> $DIR/issue-24949-assoc-const-static-recursion-impl.rs:7:1 + | +LL | const IMPL_REF_BAR: u32 = GlobalImplRef::BAR; + | ^^^^^^^^^^^^^^^^^^^^^^^ +note: ...which requires simplifying constant for the type system `IMPL_REF_BAR`... --> $DIR/issue-24949-assoc-const-static-recursion-impl.rs:7:1 | LL | const IMPL_REF_BAR: u32 = GlobalImplRef::BAR; @@ -14,6 +19,11 @@ note: ...which requires const-evaluating + checking `IMPL_REF_BAR`... | LL | const IMPL_REF_BAR: u32 = GlobalImplRef::BAR; | ^^^^^^^^^^^^^^^^^^ +note: ...which requires simplifying constant for the type system `<impl at $DIR/issue-24949-assoc-const-static-recursion-impl.rs:11:1: 11:19>::BAR`... + --> $DIR/issue-24949-assoc-const-static-recursion-impl.rs:12:5 + | +LL | const BAR: u32 = IMPL_REF_BAR; + | ^^^^^^^^^^^^^^ note: ...which requires const-evaluating + checking `<impl at $DIR/issue-24949-assoc-const-static-recursion-impl.rs:11:1: 11:19>::BAR`... --> $DIR/issue-24949-assoc-const-static-recursion-impl.rs:12:5 | diff --git a/tests/ui/associated-consts/issue-24949-assoc-const-static-recursion-trait-default.stderr b/tests/ui/associated-consts/issue-24949-assoc-const-static-recursion-trait-default.stderr index 8277d41a1c9..392cd5e3443 100644 --- a/tests/ui/associated-consts/issue-24949-assoc-const-static-recursion-trait-default.stderr +++ b/tests/ui/associated-consts/issue-24949-assoc-const-static-recursion-trait-default.stderr @@ -4,7 +4,12 @@ error[E0391]: cycle detected when elaborating drops for `FooDefault::BAR` LL | const BAR: u32 = DEFAULT_REF_BAR; | ^^^^^^^^^^^^^^^ | -note: ...which requires const-evaluating + checking `DEFAULT_REF_BAR`... +note: ...which requires simplifying constant for the type system `DEFAULT_REF_BAR`... + --> $DIR/issue-24949-assoc-const-static-recursion-trait-default.rs:11:1 + | +LL | const DEFAULT_REF_BAR: u32 = <GlobalDefaultRef>::BAR; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ +note: ...which requires simplifying constant for the type system `DEFAULT_REF_BAR`... --> $DIR/issue-24949-assoc-const-static-recursion-trait-default.rs:11:1 | LL | const DEFAULT_REF_BAR: u32 = <GlobalDefaultRef>::BAR; @@ -14,6 +19,11 @@ note: ...which requires const-evaluating + checking `DEFAULT_REF_BAR`... | LL | const DEFAULT_REF_BAR: u32 = <GlobalDefaultRef>::BAR; | ^^^^^^^^^^^^^^^^^^^^^^^ +note: ...which requires simplifying constant for the type system `FooDefault::BAR`... + --> $DIR/issue-24949-assoc-const-static-recursion-trait-default.rs:8:5 + | +LL | const BAR: u32 = DEFAULT_REF_BAR; + | ^^^^^^^^^^^^^^ note: ...which requires const-evaluating + checking `FooDefault::BAR`... --> $DIR/issue-24949-assoc-const-static-recursion-trait-default.rs:8:5 | diff --git a/tests/ui/associated-consts/issue-24949-assoc-const-static-recursion-trait.stderr b/tests/ui/associated-consts/issue-24949-assoc-const-static-recursion-trait.stderr index 9983ba794cd..6cbddca9c62 100644 --- a/tests/ui/associated-consts/issue-24949-assoc-const-static-recursion-trait.stderr +++ b/tests/ui/associated-consts/issue-24949-assoc-const-static-recursion-trait.stderr @@ -4,7 +4,12 @@ error[E0391]: cycle detected when elaborating drops for `<impl at $DIR/issue-249 LL | const BAR: u32 = TRAIT_REF_BAR; | ^^^^^^^^^^^^^ | -note: ...which requires const-evaluating + checking `TRAIT_REF_BAR`... +note: ...which requires simplifying constant for the type system `TRAIT_REF_BAR`... + --> $DIR/issue-24949-assoc-const-static-recursion-trait.rs:7:1 + | +LL | const TRAIT_REF_BAR: u32 = <GlobalTraitRef>::BAR; + | ^^^^^^^^^^^^^^^^^^^^^^^^ +note: ...which requires simplifying constant for the type system `TRAIT_REF_BAR`... --> $DIR/issue-24949-assoc-const-static-recursion-trait.rs:7:1 | LL | const TRAIT_REF_BAR: u32 = <GlobalTraitRef>::BAR; @@ -14,6 +19,11 @@ note: ...which requires const-evaluating + checking `TRAIT_REF_BAR`... | LL | const TRAIT_REF_BAR: u32 = <GlobalTraitRef>::BAR; | ^^^^^^^^^^^^^^^^^^^^^ +note: ...which requires simplifying constant for the type system `<impl at $DIR/issue-24949-assoc-const-static-recursion-trait.rs:11:1: 11:28>::BAR`... + --> $DIR/issue-24949-assoc-const-static-recursion-trait.rs:12:5 + | +LL | const BAR: u32 = TRAIT_REF_BAR; + | ^^^^^^^^^^^^^^ note: ...which requires const-evaluating + checking `<impl at $DIR/issue-24949-assoc-const-static-recursion-trait.rs:11:1: 11:28>::BAR`... --> $DIR/issue-24949-assoc-const-static-recursion-trait.rs:12:5 | diff --git a/tests/ui/associated-types/associated-types-ICE-when-projecting-out-of-err.stderr b/tests/ui/associated-types/associated-types-ICE-when-projecting-out-of-err.stderr index 8c3463a2832..fbc4ccd4cf4 100644 --- a/tests/ui/associated-types/associated-types-ICE-when-projecting-out-of-err.stderr +++ b/tests/ui/associated-types/associated-types-ICE-when-projecting-out-of-err.stderr @@ -3,6 +3,12 @@ error[E0277]: the trait bound `(): Add<A>` is not satisfied | LL | r = r + a; | ^ the trait `Add<A>` is not implemented for `()` + | +help: this trait has no implementations, consider adding one + --> $DIR/associated-types-ICE-when-projecting-out-of-err.rs:15:1 + | +LL | trait Add<RHS=Self> { + | ^^^^^^^^^^^^^^^^^^^ error: aborting due to previous error diff --git a/tests/ui/associated-types/associated-types-no-suitable-supertrait.stderr b/tests/ui/associated-types/associated-types-no-suitable-supertrait.stderr index bd3ee2abd2c..b3f2e16ba0d 100644 --- a/tests/ui/associated-types/associated-types-no-suitable-supertrait.stderr +++ b/tests/ui/associated-types/associated-types-no-suitable-supertrait.stderr @@ -3,6 +3,12 @@ error[E0277]: the trait bound `(T, U): Get` is not satisfied | LL | fn uhoh<U:Get>(&self, foo: U, bar: <(T, U) as Get>::Value) {} | ^^^^^^^^^^^^^^^^^^^^^^ the trait `Get` is not implemented for `(T, U)` + | +help: this trait has no implementations, consider adding one + --> $DIR/associated-types-no-suitable-supertrait.rs:12:1 + | +LL | trait Get { + | ^^^^^^^^^ error[E0277]: the trait bound `Self: Get` is not satisfied --> $DIR/associated-types-no-suitable-supertrait.rs:17:40 diff --git a/tests/ui/associated-types/defaults-suitability.stderr b/tests/ui/associated-types/defaults-suitability.stderr index 4b2094691f8..0a8ad0f89e2 100644 --- a/tests/ui/associated-types/defaults-suitability.stderr +++ b/tests/ui/associated-types/defaults-suitability.stderr @@ -58,6 +58,11 @@ error[E0277]: the trait bound `(): Foo<Self>` is not satisfied LL | type Assoc: Foo<Self> = (); | ^^ the trait `Foo<Self>` is not implemented for `()` | +help: this trait has no implementations, consider adding one + --> $DIR/defaults-suitability.rs:27:1 + | +LL | trait Foo<T> { + | ^^^^^^^^^^^^ note: required by a bound in `Bar::Assoc` --> $DIR/defaults-suitability.rs:34:17 | diff --git a/tests/ui/associated-types/issue-59324.stderr b/tests/ui/associated-types/issue-59324.stderr index a84b599b52b..266e22d4726 100644 --- a/tests/ui/associated-types/issue-59324.stderr +++ b/tests/ui/associated-types/issue-59324.stderr @@ -48,6 +48,12 @@ error[E0277]: the trait bound `(): Foo` is not satisfied | LL | fn with_factory<H>(factory: dyn ThriftService<()>) {} | ^^^^^^^^^^^^^^^^^^^^^ the trait `Foo` is not implemented for `()` + | +help: this trait has no implementations, consider adding one + --> $DIR/issue-59324.rs:3:1 + | +LL | pub trait Foo: NotFoo { + | ^^^^^^^^^^^^^^^^^^^^^ error[E0277]: the trait bound `Bug: Foo` is not satisfied --> $DIR/issue-59324.rs:19:10 diff --git a/tests/ui/associated-types/issue-64855.stderr b/tests/ui/associated-types/issue-64855.stderr index 6ad795c1117..f1016f0e3a1 100644 --- a/tests/ui/associated-types/issue-64855.stderr +++ b/tests/ui/associated-types/issue-64855.stderr @@ -3,6 +3,12 @@ error[E0277]: the trait bound `Bar<T>: Foo` is not satisfied | LL | pub struct Bar<T>(<Self as Foo>::Type) where Self: ; | ^^^^^^^^^^^^^^^^^^^ the trait `Foo` is not implemented for `Bar<T>` + | +help: this trait has no implementations, consider adding one + --> $DIR/issue-64855.rs:1:1 + | +LL | pub trait Foo { + | ^^^^^^^^^^^^^ error: aborting due to previous error diff --git a/tests/ui/associated-types/point-at-type-on-obligation-failure-2.stderr b/tests/ui/associated-types/point-at-type-on-obligation-failure-2.stderr index 3b4689e08cc..056d9201b4a 100644 --- a/tests/ui/associated-types/point-at-type-on-obligation-failure-2.stderr +++ b/tests/ui/associated-types/point-at-type-on-obligation-failure-2.stderr @@ -4,6 +4,11 @@ error[E0277]: the trait bound `bool: Bar` is not satisfied LL | type Assoc = bool; | ^^^^ the trait `Bar` is not implemented for `bool` | +help: this trait has no implementations, consider adding one + --> $DIR/point-at-type-on-obligation-failure-2.rs:1:1 + | +LL | trait Bar {} + | ^^^^^^^^^ note: required by a bound in `Foo::Assoc` --> $DIR/point-at-type-on-obligation-failure-2.rs:4:17 | @@ -16,6 +21,11 @@ error[E0277]: the trait bound `bool: Bar` is not satisfied LL | type Assoc = bool; | ^^^^ the trait `Bar` is not implemented for `bool` | +help: this trait has no implementations, consider adding one + --> $DIR/point-at-type-on-obligation-failure-2.rs:1:1 + | +LL | trait Bar {} + | ^^^^^^^^^ note: required by a bound in `Baz::Assoc` --> $DIR/point-at-type-on-obligation-failure-2.rs:13:18 | @@ -31,6 +41,11 @@ error[E0277]: the trait bound `bool: Bar` is not satisfied LL | type Assoc = bool; | ^^^^ the trait `Bar` is not implemented for `bool` | +help: this trait has no implementations, consider adding one + --> $DIR/point-at-type-on-obligation-failure-2.rs:1:1 + | +LL | trait Bar {} + | ^^^^^^^^^ note: required by a bound in `Bat::Assoc` --> $DIR/point-at-type-on-obligation-failure-2.rs:24:27 | diff --git a/tests/ui/async-await/in-trait/indirect-recursion-issue-112047.rs b/tests/ui/async-await/in-trait/indirect-recursion-issue-112047.rs new file mode 100644 index 00000000000..85d17ddff94 --- /dev/null +++ b/tests/ui/async-await/in-trait/indirect-recursion-issue-112047.rs @@ -0,0 +1,38 @@ +// edition: 2021 +// build-fail +//~^^ ERROR overflow evaluating the requirement `<A as Second>::{opaque#0} == _` + +#![feature(async_fn_in_trait)] + +fn main() { + let _ = async { + A.first().await.second().await; + }; +} + +pub trait First { + type Second: Second; + async fn first(self) -> Self::Second; +} + +struct A; + +impl First for A { + type Second = A; + async fn first(self) -> Self::Second { + A + } +} + +pub trait Second { + async fn second(self); +} + +impl<C> Second for C +where + C: First, +{ + async fn second(self) { + self.first().await.second().await; + } +} diff --git a/tests/ui/async-await/in-trait/indirect-recursion-issue-112047.stderr b/tests/ui/async-await/in-trait/indirect-recursion-issue-112047.stderr new file mode 100644 index 00000000000..3f487a6e5fe --- /dev/null +++ b/tests/ui/async-await/in-trait/indirect-recursion-issue-112047.stderr @@ -0,0 +1,5 @@ +error[E0275]: overflow evaluating the requirement `<A as Second>::{opaque#0} == _` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0275`. diff --git a/tests/ui/async-await/issues/issue-66695-static-refs.rs b/tests/ui/async-await/issues/issue-66695-static-refs.rs index f0609713b4d..1b0e1c6c9e7 100644 --- a/tests/ui/async-await/issues/issue-66695-static-refs.rs +++ b/tests/ui/async-await/issues/issue-66695-static-refs.rs @@ -1,12 +1,15 @@ // build-pass // edition:2018 +#![feature(if_let_guard)] + static A: [i32; 5] = [1, 2, 3, 4, 5]; async fn fun() { let u = A[async { 1 }.await]; match A { i if async { true }.await => (), + i if let Some(1) = async { Some(1) }.await => (), _ => (), } } @@ -18,6 +21,7 @@ fn main() { async { match A { i if async { true }.await => (), + i if let Some(2) = async { Some(2) }.await => (), _ => (), } }; diff --git a/tests/ui/async-await/issues/issue-67611-static-mut-refs.rs b/tests/ui/async-await/issues/issue-67611-static-mut-refs.rs index c4f8f607d25..80d824d3b2e 100644 --- a/tests/ui/async-await/issues/issue-67611-static-mut-refs.rs +++ b/tests/ui/async-await/issues/issue-67611-static-mut-refs.rs @@ -5,6 +5,8 @@ // [drop_tracking] compile-flags: -Zdrop-tracking // [drop_tracking_mir] compile-flags: -Zdrop-tracking-mir +#![feature(if_let_guard)] + static mut A: [i32; 5] = [1, 2, 3, 4, 5]; fn is_send_sync<T: Send + Sync>(_: T) {} @@ -14,6 +16,7 @@ async fn fun() { unsafe { match A { i if async { true }.await => (), + i if let Some(1) = async { Some(1) }.await => (), _ => (), } } @@ -27,6 +30,7 @@ fn main() { unsafe { match A { i if async { true }.await => (), + i if let Some(2) = async { Some(2) }.await => (), _ => (), } } diff --git a/tests/ui/async-await/missed-capture-issue-107414.rs b/tests/ui/async-await/missed-capture-issue-107414.rs index 0ab4f5ade98..bb14eb74b3a 100644 --- a/tests/ui/async-await/missed-capture-issue-107414.rs +++ b/tests/ui/async-await/missed-capture-issue-107414.rs @@ -1,6 +1,8 @@ // check-pass // edition:2018 +#![feature(if_let_guard)] + fn main() {} struct StructA {} @@ -22,3 +24,10 @@ async fn ice() { _ => {} } } + +async fn if_let() { + match Some(StructB {}) { + Some(struct_b) if let true = get_struct_a_async().await.fn_taking_struct_b(&struct_b) => {} + _ => {} + } +} diff --git a/tests/ui/async-await/return-type-notation/normalizing-self-auto-trait-issue-109924.current.stderr b/tests/ui/async-await/return-type-notation/normalizing-self-auto-trait-issue-109924.current.stderr index 3b63ec45804..8f45902035e 100644 --- a/tests/ui/async-await/return-type-notation/normalizing-self-auto-trait-issue-109924.current.stderr +++ b/tests/ui/async-await/return-type-notation/normalizing-self-auto-trait-issue-109924.current.stderr @@ -16,6 +16,14 @@ LL | build(Bar); | required by a bound introduced by this call | = help: the trait `for<'a> Send` is not implemented for `impl Future<Output = ()> { <_ as Foo>::bar() }` +note: this is a known limitation of the trait solver that will be lifted in the future + --> $DIR/normalizing-self-auto-trait-issue-109924.rs:23:11 + | +LL | build(Bar); + | ------^^^- + | | | + | | the trait solver is unable to infer the generic types that should be inferred from this argument + | add turbofish arguments to this call to specify the types manually, even if it's redundant note: required by a bound in `build` --> $DIR/normalizing-self-auto-trait-issue-109924.rs:20:39 | diff --git a/tests/ui/binding/match-beginning-vert.rs b/tests/ui/binding/match-beginning-vert.rs index 79267400b28..93c08f0b710 100644 --- a/tests/ui/binding/match-beginning-vert.rs +++ b/tests/ui/binding/match-beginning-vert.rs @@ -1,4 +1,7 @@ // run-pass + +#![feature(if_let_guard)] + enum Foo { A, B, @@ -13,6 +16,7 @@ fn main() { match *foo { | A => println!("A"), | B | C if 1 < 2 => println!("BC!"), + | D if let 1 = 1 => println!("D!"), | _ => {}, } } diff --git a/tests/ui/borrowck/issue-115259-suggest-iter-mut.fixed b/tests/ui/borrowck/issue-115259-suggest-iter-mut.fixed new file mode 100644 index 00000000000..4653fe7375d --- /dev/null +++ b/tests/ui/borrowck/issue-115259-suggest-iter-mut.fixed @@ -0,0 +1,20 @@ +// run-rustfix +#![allow(unused_mut)] +#![allow(dead_code)] + +pub trait Layer { + fn process(&mut self) -> u32; +} + +pub struct State { + layers: Vec<Box<dyn Layer>>, +} + +impl State { + pub fn process(&mut self) -> u32 { + self.layers.iter_mut().fold(0, |result, mut layer| result + layer.process()) + //~^ ERROR cannot borrow `**layer` as mutable, as it is behind a `&` reference + } +} + +fn main() {} diff --git a/tests/ui/borrowck/issue-115259-suggest-iter-mut.rs b/tests/ui/borrowck/issue-115259-suggest-iter-mut.rs new file mode 100644 index 00000000000..e0f6ab1321f --- /dev/null +++ b/tests/ui/borrowck/issue-115259-suggest-iter-mut.rs @@ -0,0 +1,20 @@ +// run-rustfix +#![allow(unused_mut)] +#![allow(dead_code)] + +pub trait Layer { + fn process(&mut self) -> u32; +} + +pub struct State { + layers: Vec<Box<dyn Layer>>, +} + +impl State { + pub fn process(&mut self) -> u32 { + self.layers.iter().fold(0, |result, mut layer| result + layer.process()) + //~^ ERROR cannot borrow `**layer` as mutable, as it is behind a `&` reference + } +} + +fn main() {} diff --git a/tests/ui/borrowck/issue-115259-suggest-iter-mut.stderr b/tests/ui/borrowck/issue-115259-suggest-iter-mut.stderr new file mode 100644 index 00000000000..7e0fc2cf298 --- /dev/null +++ b/tests/ui/borrowck/issue-115259-suggest-iter-mut.stderr @@ -0,0 +1,16 @@ +error[E0596]: cannot borrow `**layer` as mutable, as it is behind a `&` reference + --> $DIR/issue-115259-suggest-iter-mut.rs:15:65 + | +LL | self.layers.iter().fold(0, |result, mut layer| result + layer.process()) + | --------- ^^^^^ `layer` is a `&` reference, so the data it refers to cannot be borrowed as mutable + | | + | consider changing this binding's type to be: `&mut Box<dyn Layer>` + | +help: you may want to use `iter_mut` here + | +LL | self.layers.iter_mut().fold(0, |result, mut layer| result + layer.process()) + | ~~~~~~~~ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0596`. diff --git a/tests/ui/borrowck/issue-62387-suggest-iter-mut-2.fixed b/tests/ui/borrowck/issue-62387-suggest-iter-mut-2.fixed new file mode 100644 index 00000000000..f02374d8e11 --- /dev/null +++ b/tests/ui/borrowck/issue-62387-suggest-iter-mut-2.fixed @@ -0,0 +1,36 @@ +// run-rustfix +#![allow(unused_mut)] +#![allow(dead_code)] +use std::path::PathBuf; + +#[derive(Clone)] +struct Container { + things: Vec<PathBuf>, +} + +impl Container { + fn things(&mut self) -> &[PathBuf] { + &self.things + } +} + +// contains containers +struct ContainerContainer { + contained: Vec<Container>, +} + +impl ContainerContainer { + fn contained(&self) -> &[Container] { + &self.contained + } + + fn all_the_things(&mut self) -> &[PathBuf] { + let mut vec = self.contained.clone(); + let _a = + vec.iter_mut().flat_map(|container| container.things()).cloned().collect::<Vec<PathBuf>>(); + //~^ ERROR cannot borrow `*container` as mutable, as it is behind a `&` reference + unimplemented!(); + } +} + +fn main() {} diff --git a/tests/ui/borrowck/issue-62387-suggest-iter-mut-2.rs b/tests/ui/borrowck/issue-62387-suggest-iter-mut-2.rs new file mode 100644 index 00000000000..2d0b837a946 --- /dev/null +++ b/tests/ui/borrowck/issue-62387-suggest-iter-mut-2.rs @@ -0,0 +1,36 @@ +// run-rustfix +#![allow(unused_mut)] +#![allow(dead_code)] +use std::path::PathBuf; + +#[derive(Clone)] +struct Container { + things: Vec<PathBuf>, +} + +impl Container { + fn things(&mut self) -> &[PathBuf] { + &self.things + } +} + +// contains containers +struct ContainerContainer { + contained: Vec<Container>, +} + +impl ContainerContainer { + fn contained(&self) -> &[Container] { + &self.contained + } + + fn all_the_things(&mut self) -> &[PathBuf] { + let mut vec = self.contained.clone(); + let _a = + vec.iter().flat_map(|container| container.things()).cloned().collect::<Vec<PathBuf>>(); + //~^ ERROR cannot borrow `*container` as mutable, as it is behind a `&` reference + unimplemented!(); + } +} + +fn main() {} diff --git a/tests/ui/borrowck/issue-62387-suggest-iter-mut-2.stderr b/tests/ui/borrowck/issue-62387-suggest-iter-mut-2.stderr new file mode 100644 index 00000000000..19f194100a1 --- /dev/null +++ b/tests/ui/borrowck/issue-62387-suggest-iter-mut-2.stderr @@ -0,0 +1,16 @@ +error[E0596]: cannot borrow `*container` as mutable, as it is behind a `&` reference + --> $DIR/issue-62387-suggest-iter-mut-2.rs:30:45 + | +LL | vec.iter().flat_map(|container| container.things()).cloned().collect::<Vec<PathBuf>>(); + | --------- ^^^^^^^^^ `container` is a `&` reference, so the data it refers to cannot be borrowed as mutable + | | + | consider changing this binding's type to be: `&mut Container` + | +help: you may want to use `iter_mut` here + | +LL | vec.iter_mut().flat_map(|container| container.things()).cloned().collect::<Vec<PathBuf>>(); + | ~~~~~~~~ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0596`. diff --git a/tests/ui/borrowck/issue-62387-suggest-iter-mut.fixed b/tests/ui/borrowck/issue-62387-suggest-iter-mut.fixed new file mode 100644 index 00000000000..8bf2625de6d --- /dev/null +++ b/tests/ui/borrowck/issue-62387-suggest-iter-mut.fixed @@ -0,0 +1,30 @@ +// run-rustfix +#![allow(unused_mut)] +#![allow(dead_code)] + +#[derive(Debug)] +struct A { + a: i32, +} + +impl A { + fn double(&mut self) { + self.a += self.a + } +} + +fn baz() { + let mut v = [A { a: 4 }]; + v.iter_mut().for_each(|a| a.double()); + //~^ ERROR cannot borrow `*a` as mutable, as it is behind a `&` reference + println!("{:?}", v); +} + +fn bar() { + let mut v = [A { a: 4 }]; + v.iter_mut().rev().rev().for_each(|a| a.double()); + //~^ ERROR cannot borrow `*a` as mutable, as it is behind a `&` reference + println!("{:?}", v); +} + +fn main() {} diff --git a/tests/ui/borrowck/issue-62387-suggest-iter-mut.rs b/tests/ui/borrowck/issue-62387-suggest-iter-mut.rs new file mode 100644 index 00000000000..39bc30bf294 --- /dev/null +++ b/tests/ui/borrowck/issue-62387-suggest-iter-mut.rs @@ -0,0 +1,30 @@ +// run-rustfix +#![allow(unused_mut)] +#![allow(dead_code)] + +#[derive(Debug)] +struct A { + a: i32, +} + +impl A { + fn double(&mut self) { + self.a += self.a + } +} + +fn baz() { + let mut v = [A { a: 4 }]; + v.iter().for_each(|a| a.double()); + //~^ ERROR cannot borrow `*a` as mutable, as it is behind a `&` reference + println!("{:?}", v); +} + +fn bar() { + let mut v = [A { a: 4 }]; + v.iter().rev().rev().for_each(|a| a.double()); + //~^ ERROR cannot borrow `*a` as mutable, as it is behind a `&` reference + println!("{:?}", v); +} + +fn main() {} diff --git a/tests/ui/borrowck/issue-62387-suggest-iter-mut.stderr b/tests/ui/borrowck/issue-62387-suggest-iter-mut.stderr new file mode 100644 index 00000000000..fd58e433020 --- /dev/null +++ b/tests/ui/borrowck/issue-62387-suggest-iter-mut.stderr @@ -0,0 +1,29 @@ +error[E0596]: cannot borrow `*a` as mutable, as it is behind a `&` reference + --> $DIR/issue-62387-suggest-iter-mut.rs:18:27 + | +LL | v.iter().for_each(|a| a.double()); + | - ^ `a` is a `&` reference, so the data it refers to cannot be borrowed as mutable + | | + | consider changing this binding's type to be: `&mut A` + | +help: you may want to use `iter_mut` here + | +LL | v.iter_mut().for_each(|a| a.double()); + | ~~~~~~~~ + +error[E0596]: cannot borrow `*a` as mutable, as it is behind a `&` reference + --> $DIR/issue-62387-suggest-iter-mut.rs:25:39 + | +LL | v.iter().rev().rev().for_each(|a| a.double()); + | - ^ `a` is a `&` reference, so the data it refers to cannot be borrowed as mutable + | | + | consider changing this binding's type to be: `&mut A` + | +help: you may want to use `iter_mut` here + | +LL | v.iter_mut().rev().rev().for_each(|a| a.double()); + | ~~~~~~~~ + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0596`. diff --git a/tests/ui/borrowck/issue-81899.stderr b/tests/ui/borrowck/issue-81899.stderr index 1b03bc3af9c..63e817239c6 100644 --- a/tests/ui/borrowck/issue-81899.stderr +++ b/tests/ui/borrowck/issue-81899.stderr @@ -16,7 +16,7 @@ LL | const _CONST: &[u8] = &f(&[], |_| {}); | ^^^^^^^^^^^^^^ = note: this error originates in the macro `$crate::panic::panic_2015` which comes from the expansion of the macro `panic` (in Nightly builds, run with -Z macro-backtrace for more info) -note: erroneous constant used +note: erroneous constant encountered --> $DIR/issue-81899.rs:4:23 | LL | const _CONST: &[u8] = &f(&[], |_| {}); diff --git a/tests/ui/borrowck/issue-88434-minimal-example.stderr b/tests/ui/borrowck/issue-88434-minimal-example.stderr index a5a571c6d4d..4c887b2ad42 100644 --- a/tests/ui/borrowck/issue-88434-minimal-example.stderr +++ b/tests/ui/borrowck/issue-88434-minimal-example.stderr @@ -16,7 +16,7 @@ LL | const _CONST: &() = &f(&|_| {}); | ^^^^^^^^^^ = note: this error originates in the macro `$crate::panic::panic_2015` which comes from the expansion of the macro `panic` (in Nightly builds, run with -Z macro-backtrace for more info) -note: erroneous constant used +note: erroneous constant encountered --> $DIR/issue-88434-minimal-example.rs:3:21 | LL | const _CONST: &() = &f(&|_| {}); diff --git a/tests/ui/borrowck/issue-88434-removal-index-should-be-less.stderr b/tests/ui/borrowck/issue-88434-removal-index-should-be-less.stderr index 00023c459a8..f7257817a8b 100644 --- a/tests/ui/borrowck/issue-88434-removal-index-should-be-less.stderr +++ b/tests/ui/borrowck/issue-88434-removal-index-should-be-less.stderr @@ -16,7 +16,7 @@ LL | const _CONST: &[u8] = &f(&[], |_| {}); | ^^^^^^^^^^^^^^ = note: this error originates in the macro `$crate::panic::panic_2015` which comes from the expansion of the macro `panic` (in Nightly builds, run with -Z macro-backtrace for more info) -note: erroneous constant used +note: erroneous constant encountered --> $DIR/issue-88434-removal-index-should-be-less.rs:3:23 | LL | const _CONST: &[u8] = &f(&[], |_| {}); diff --git a/tests/ui/c-variadic/variadic-ffi-2.rs b/tests/ui/c-variadic/variadic-ffi-2.rs index c34b7e55f6a..67a0a9a1dec 100644 --- a/tests/ui/c-variadic/variadic-ffi-2.rs +++ b/tests/ui/c-variadic/variadic-ffi-2.rs @@ -3,10 +3,13 @@ fn baz(f: extern "stdcall" fn(usize, ...)) { //~^ ERROR: C-variadic function must have a compatible calling convention, - // like C, cdecl, win64, sysv64 or efiapi + // like C, cdecl, aapcs, win64, sysv64 or efiapi f(22, 44); } +fn aapcs(f: extern "aapcs" fn(usize, ...)) { + f(22, 44); +} fn sysv(f: extern "sysv64" fn(usize, ...)) { f(22, 44); } diff --git a/tests/ui/c-variadic/variadic-ffi-2.stderr b/tests/ui/c-variadic/variadic-ffi-2.stderr index e21001ecaf8..8884fc6fb2a 100644 --- a/tests/ui/c-variadic/variadic-ffi-2.stderr +++ b/tests/ui/c-variadic/variadic-ffi-2.stderr @@ -1,4 +1,4 @@ -error[E0045]: C-variadic function must have a compatible calling convention, like `C`, `cdecl`, `win64`, `sysv64` or `efiapi` +error[E0045]: C-variadic function must have a compatible calling convention, like `C`, `cdecl`, `aapcs`, `win64`, `sysv64` or `efiapi` --> $DIR/variadic-ffi-2.rs:4:11 | LL | fn baz(f: extern "stdcall" fn(usize, ...)) { diff --git a/tests/ui/cast/cast-as-bool.rs b/tests/ui/cast/cast-as-bool.rs index fbebc80d91c..511a02718fe 100644 --- a/tests/ui/cast/cast-as-bool.rs +++ b/tests/ui/cast/cast-as-bool.rs @@ -1,11 +1,47 @@ fn main() { - let u = 5 as bool; //~ ERROR cannot cast as `bool` + let u = 5 as bool; //~ ERROR cannot cast `i32` as `bool` //~| HELP compare with zero instead - //~| SUGGESTION 5 != 0 + //~| SUGGESTION != 0 - let t = (1 + 2) as bool; //~ ERROR cannot cast as `bool` + let t = (1 + 2) as bool; //~ ERROR cannot cast `i32` as `bool` //~| HELP compare with zero instead - //~| SUGGESTION (1 + 2) != 0 + //~| SUGGESTION != 0 + + let _ = 5_u32 as bool; //~ ERROR cannot cast `u32` as `bool` + //~| HELP compare with zero instead + + let _ = 64.0_f64 as bool; //~ ERROR cannot cast `f64` as `bool` + //~| HELP compare with zero instead + + // Enums that can normally be cast to integers can't be cast to `bool`, just like integers. + // Note that enums that cannot be cast to integers can't be cast to anything at *all* + // so that's not tested here. + enum IntEnum { + Zero, + One, + Two + } + let _ = IntEnum::One as bool; //~ ERROR cannot cast `IntEnum` as `bool` + + fn uwu(_: u8) -> String { + todo!() + } + + unsafe fn owo() {} + + // fn item to bool + let _ = uwu as bool; //~ ERROR cannot cast `fn(u8) -> String {uwu}` as `bool` + // unsafe fn item + let _ = owo as bool; //~ ERROR cannot cast `unsafe fn() {owo}` as `bool` + + // fn ptr to bool + let _ = uwu as fn(u8) -> String as bool; //~ ERROR cannot cast `fn(u8) -> String` as `bool` + + let _ = 'x' as bool; //~ ERROR cannot cast `char` as `bool` + + let ptr = 1 as *const (); + + let _ = ptr as bool; //~ ERROR cannot cast `*const ()` as `bool` let v = "hello" as bool; //~^ ERROR casting `&'static str` as `bool` is invalid diff --git a/tests/ui/cast/cast-as-bool.stderr b/tests/ui/cast/cast-as-bool.stderr index 19ac8f10fec..4ff56a95e49 100644 --- a/tests/ui/cast/cast-as-bool.stderr +++ b/tests/ui/cast/cast-as-bool.stderr @@ -1,18 +1,86 @@ -error[E0054]: cannot cast as `bool` +error[E0054]: cannot cast `i32` as `bool` --> $DIR/cast-as-bool.rs:2:13 | LL | let u = 5 as bool; - | ^^^^^^^^^ help: compare with zero instead: `5 != 0` + | ^^^^^^^^^ + | +help: compare with zero instead + | +LL | let u = 5 != 0; + | ~~~~ -error[E0054]: cannot cast as `bool` +error[E0054]: cannot cast `i32` as `bool` --> $DIR/cast-as-bool.rs:6:13 | LL | let t = (1 + 2) as bool; - | ^^^^^^^^^^^^^^^ help: compare with zero instead: `(1 + 2) != 0` + | ^^^^^^^^^^^^^^^ + | +help: compare with zero instead + | +LL | let t = (1 + 2) != 0; + | ~~~~ -error[E0606]: casting `&'static str` as `bool` is invalid +error[E0054]: cannot cast `u32` as `bool` --> $DIR/cast-as-bool.rs:10:13 | +LL | let _ = 5_u32 as bool; + | ^^^^^^^^^^^^^ + | +help: compare with zero instead + | +LL | let _ = 5_u32 != 0; + | ~~~~ + +error[E0054]: cannot cast `f64` as `bool` + --> $DIR/cast-as-bool.rs:13:13 + | +LL | let _ = 64.0_f64 as bool; + | ^^^^^^^^^^^^^^^^ + | +help: compare with zero instead + | +LL | let _ = 64.0_f64 != 0; + | ~~~~ + +error[E0054]: cannot cast `IntEnum` as `bool` + --> $DIR/cast-as-bool.rs:24:13 + | +LL | let _ = IntEnum::One as bool; + | ^^^^^^^^^^^^^^^^^^^^ unsupported cast + +error[E0054]: cannot cast `fn(u8) -> String {uwu}` as `bool` + --> $DIR/cast-as-bool.rs:33:13 + | +LL | let _ = uwu as bool; + | ^^^^^^^^^^^ unsupported cast + +error[E0054]: cannot cast `unsafe fn() {owo}` as `bool` + --> $DIR/cast-as-bool.rs:35:13 + | +LL | let _ = owo as bool; + | ^^^^^^^^^^^ unsupported cast + +error[E0054]: cannot cast `fn(u8) -> String` as `bool` + --> $DIR/cast-as-bool.rs:38:13 + | +LL | let _ = uwu as fn(u8) -> String as bool; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unsupported cast + +error[E0054]: cannot cast `char` as `bool` + --> $DIR/cast-as-bool.rs:40:13 + | +LL | let _ = 'x' as bool; + | ^^^^^^^^^^^ unsupported cast + +error[E0054]: cannot cast `*const ()` as `bool` + --> $DIR/cast-as-bool.rs:44:13 + | +LL | let _ = ptr as bool; + | ^^^^^^^^^^^ unsupported cast + +error[E0606]: casting `&'static str` as `bool` is invalid + --> $DIR/cast-as-bool.rs:46:13 + | LL | let v = "hello" as bool; | ^^^^^^^^^^^^^^^ | @@ -21,7 +89,7 @@ help: consider using the `is_empty` method on `&'static str` to determine if it LL | let v = !"hello".is_empty(); | + ~~~~~~~~~~~ -error: aborting due to 3 previous errors +error: aborting due to 11 previous errors Some errors have detailed explanations: E0054, E0606. For more information about an error, try `rustc --explain E0054`. diff --git a/tests/ui/cast/cast-rfc0401-2.rs b/tests/ui/cast/cast-rfc0401-2.rs index 7709aa34104..70604a587ea 100644 --- a/tests/ui/cast/cast-rfc0401-2.rs +++ b/tests/ui/cast/cast-rfc0401-2.rs @@ -4,5 +4,5 @@ fn main() { let _ = 3 as bool; - //~^ ERROR cannot cast as `bool` + //~^ ERROR cannot cast `i32` as `bool` } diff --git a/tests/ui/cast/cast-rfc0401-2.stderr b/tests/ui/cast/cast-rfc0401-2.stderr index 52f6af78a9b..dd90c3a9723 100644 --- a/tests/ui/cast/cast-rfc0401-2.stderr +++ b/tests/ui/cast/cast-rfc0401-2.stderr @@ -1,8 +1,13 @@ -error[E0054]: cannot cast as `bool` +error[E0054]: cannot cast `i32` as `bool` --> $DIR/cast-rfc0401-2.rs:6:13 | LL | let _ = 3 as bool; - | ^^^^^^^^^ help: compare with zero instead: `3 != 0` + | ^^^^^^^^^ + | +help: compare with zero instead + | +LL | let _ = 3 != 0; + | ~~~~ error: aborting due to previous error diff --git a/tests/ui/closures/2229_closure_analysis/repr_packed.rs b/tests/ui/closures/2229_closure_analysis/repr_packed.rs index f23670f63ac..8c23454fae9 100644 --- a/tests/ui/closures/2229_closure_analysis/repr_packed.rs +++ b/tests/ui/closures/2229_closure_analysis/repr_packed.rs @@ -3,7 +3,8 @@ #![feature(rustc_attrs)] // `u8` aligned at a byte and are unaffected by repr(packed). -// Therefore we can precisely (and safely) capture references to both the fields. +// Therefore we *could* precisely (and safely) capture references to both the fields, +// but we don't, since we don't want capturing to change when field types change alignment. fn test_alignment_not_affected() { #[repr(packed)] struct Foo { x: u8, y: u8 } @@ -17,11 +18,10 @@ fn test_alignment_not_affected() { //~^ ERROR: First Pass analysis includes: //~| ERROR: Min Capture analysis includes: let z1: &u8 = &foo.x; - //~^ NOTE: Capturing foo[(0, 0)] -> ImmBorrow - //~| NOTE: Min Capture foo[(0, 0)] -> ImmBorrow + //~^ NOTE: Capturing foo[] -> ImmBorrow let z2: &mut u8 = &mut foo.y; - //~^ NOTE: Capturing foo[(1, 0)] -> MutBorrow - //~| NOTE: Min Capture foo[(1, 0)] -> MutBorrow + //~^ NOTE: Capturing foo[] -> MutBorrow + //~| NOTE: Min Capture foo[] -> MutBorrow *z2 = 42; diff --git a/tests/ui/closures/2229_closure_analysis/repr_packed.stderr b/tests/ui/closures/2229_closure_analysis/repr_packed.stderr index 580061ebc6e..32b3d844c6e 100644 --- a/tests/ui/closures/2229_closure_analysis/repr_packed.stderr +++ b/tests/ui/closures/2229_closure_analysis/repr_packed.stderr @@ -1,5 +1,5 @@ error[E0658]: attributes on expressions are experimental - --> $DIR/repr_packed.rs:13:17 + --> $DIR/repr_packed.rs:14:17 | LL | let mut c = #[rustc_capture_analysis] | ^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -26,7 +26,7 @@ LL | let c = #[rustc_capture_analysis] = help: add `#![feature(stmt_expr_attributes)]` to the crate attributes to enable error: First Pass analysis includes: - --> $DIR/repr_packed.rs:16:5 + --> $DIR/repr_packed.rs:17:5 | LL | / || { LL | | @@ -37,19 +37,19 @@ LL | | println!("({}, {})", z1, z2); LL | | }; | |_____^ | -note: Capturing foo[(0, 0)] -> ImmBorrow - --> $DIR/repr_packed.rs:19:24 +note: Capturing foo[] -> ImmBorrow + --> $DIR/repr_packed.rs:20:24 | LL | let z1: &u8 = &foo.x; | ^^^^^ -note: Capturing foo[(1, 0)] -> MutBorrow +note: Capturing foo[] -> MutBorrow --> $DIR/repr_packed.rs:22:32 | LL | let z2: &mut u8 = &mut foo.y; | ^^^^^ error: Min Capture analysis includes: - --> $DIR/repr_packed.rs:16:5 + --> $DIR/repr_packed.rs:17:5 | LL | / || { LL | | @@ -60,12 +60,7 @@ LL | | println!("({}, {})", z1, z2); LL | | }; | |_____^ | -note: Min Capture foo[(0, 0)] -> ImmBorrow - --> $DIR/repr_packed.rs:19:24 - | -LL | let z1: &u8 = &foo.x; - | ^^^^^ -note: Min Capture foo[(1, 0)] -> MutBorrow +note: Min Capture foo[] -> MutBorrow --> $DIR/repr_packed.rs:22:32 | LL | let z2: &mut u8 = &mut foo.y; diff --git a/tests/ui/codegen/subtyping-enforces-type-equality.rs b/tests/ui/codegen/subtyping-enforces-type-equality.rs new file mode 100644 index 00000000000..a5ffcb3f854 --- /dev/null +++ b/tests/ui/codegen/subtyping-enforces-type-equality.rs @@ -0,0 +1,48 @@ +// ignore-pass +// build-pass +// edition:2021 +use std::future::Future; +use std::pin::Pin; + +type BoxFuture<T> = Pin<Box<dyn Future<Output = T>>>; + +fn main() { + let _ = wrapper_call(handler); +} + +async fn wrapper_call(handler: impl Handler) { + handler.call().await; +} +async fn handler() { + f(&()).await; +} +async fn f<'a>(db: impl Acquire<'a>) { + db.acquire().await; +} + +trait Handler { + type Future: Future; + fn call(self) -> Self::Future; +} + +impl<Fut, F> Handler for F +where + F: Fn() -> Fut, + Fut: Future, +{ + type Future = Fut; + fn call(self) -> Self::Future { + loop {} + } +} + +trait Acquire<'a> { + type Connection; + fn acquire(self) -> BoxFuture<Self::Connection>; +} +impl<'a> Acquire<'a> for &'a () { + type Connection = Self; + fn acquire(self) -> BoxFuture<Self> { + loop {} + } +} diff --git a/tests/ui/codegen/subtyping-enforces-type-equality.stderr b/tests/ui/codegen/subtyping-enforces-type-equality.stderr new file mode 100644 index 00000000000..870ca0f839f --- /dev/null +++ b/tests/ui/codegen/subtyping-enforces-type-equality.stderr @@ -0,0 +1 @@ +WARN rustc_codegen_ssa::mir::locals Unexpected initial operand type. See the issues/114858 diff --git a/tests/ui/coherence/coherence-unsafe-trait-object-impl.stderr b/tests/ui/coherence/coherence-unsafe-trait-object-impl.stderr index 2e2dac288a1..a3a37fd2775 100644 --- a/tests/ui/coherence/coherence-unsafe-trait-object-impl.stderr +++ b/tests/ui/coherence/coherence-unsafe-trait-object-impl.stderr @@ -6,6 +6,11 @@ LL | takes_t(t); | | | required by a bound introduced by this call | +help: this trait has no implementations, consider adding one + --> $DIR/coherence-unsafe-trait-object-impl.rs:6:1 + | +LL | trait Trait: Sized { + | ^^^^^^^^^^^^^^^^^^ note: required by a bound in `takes_t` --> $DIR/coherence-unsafe-trait-object-impl.rs:10:15 | diff --git a/tests/ui/const-generics/dont-evaluate-array-len-on-err-1.stderr b/tests/ui/const-generics/dont-evaluate-array-len-on-err-1.stderr index cb51d9b1ea5..b3a27566026 100644 --- a/tests/ui/const-generics/dont-evaluate-array-len-on-err-1.stderr +++ b/tests/ui/const-generics/dont-evaluate-array-len-on-err-1.stderr @@ -3,6 +3,12 @@ error[E0277]: the trait bound `[Adt; std::mem::size_of::<Self::Assoc>()]: Foo` i | LL | <[Adt; std::mem::size_of::<Self::Assoc>()] as Foo>::bar() | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Foo` is not implemented for `[Adt; std::mem::size_of::<Self::Assoc>()]` + | +help: this trait has no implementations, consider adding one + --> $DIR/dont-evaluate-array-len-on-err-1.rs:9:1 + | +LL | trait Foo { + | ^^^^^^^^^ error: aborting due to previous error diff --git a/tests/ui/const-generics/early/const-param-from-outer-fn.rs b/tests/ui/const-generics/early/const-param-from-outer-fn.rs index c3b418ee3f8..ee57f3c4fc3 100644 --- a/tests/ui/const-generics/early/const-param-from-outer-fn.rs +++ b/tests/ui/const-generics/early/const-param-from-outer-fn.rs @@ -1,6 +1,6 @@ fn foo<const X: u32>() { fn bar() -> u32 { - X //~ ERROR can't use generic parameters from outer function + X //~ ERROR can't use generic parameters from outer item } } diff --git a/tests/ui/const-generics/early/const-param-from-outer-fn.stderr b/tests/ui/const-generics/early/const-param-from-outer-fn.stderr index e3bf38b702e..826f2657905 100644 --- a/tests/ui/const-generics/early/const-param-from-outer-fn.stderr +++ b/tests/ui/const-generics/early/const-param-from-outer-fn.stderr @@ -1,12 +1,12 @@ -error[E0401]: can't use generic parameters from outer function +error[E0401]: can't use generic parameters from outer item --> $DIR/const-param-from-outer-fn.rs:3:9 | LL | fn foo<const X: u32>() { - | - const parameter from outer function + | - const parameter from outer item LL | fn bar() -> u32 { - | - help: try using a local generic parameter instead: `<X>` + | - help: try introducing a local generic parameter here: `<X>` LL | X - | ^ use of generic parameter from outer function + | ^ use of generic parameter from outer item error: aborting due to previous error diff --git a/tests/ui/const-generics/generic_const_exprs/issue-85848.stderr b/tests/ui/const-generics/generic_const_exprs/issue-85848.stderr index e50ac671eca..9391b1c1a17 100644 --- a/tests/ui/const-generics/generic_const_exprs/issue-85848.stderr +++ b/tests/ui/const-generics/generic_const_exprs/issue-85848.stderr @@ -6,7 +6,11 @@ LL | writes_to_specific_path(&cap); | | | required by a bound introduced by this call | - = help: the trait `Delegates<U>` is implemented for `T` +help: this trait has no implementations, consider adding one + --> $DIR/issue-85848.rs:4:1 + | +LL | trait _Contains<T> { + | ^^^^^^^^^^^^^^^^^^ note: required for `&C` to implement `Contains<(), true>` --> $DIR/issue-85848.rs:21:12 | diff --git a/tests/ui/const-generics/issues/issue-86530.stderr b/tests/ui/const-generics/issues/issue-86530.stderr index 620ed4f0fb2..d02808f7c56 100644 --- a/tests/ui/const-generics/issues/issue-86530.stderr +++ b/tests/ui/const-generics/issues/issue-86530.stderr @@ -6,6 +6,11 @@ LL | z(" "); | | | required by a bound introduced by this call | +help: this trait has no implementations, consider adding one + --> $DIR/issue-86530.rs:4:1 + | +LL | pub trait X { + | ^^^^^^^^^^^ note: required by a bound in `z` --> $DIR/issue-86530.rs:10:8 | diff --git a/tests/ui/const-generics/late-bound-vars/in_closure.rs b/tests/ui/const-generics/late-bound-vars/in_closure.rs index 6549cad629b..443c755c601 100644 --- a/tests/ui/const-generics/late-bound-vars/in_closure.rs +++ b/tests/ui/const-generics/late-bound-vars/in_closure.rs @@ -1,23 +1,5 @@ -// failure-status: 1 // known-bug: unknown -// error-pattern:internal compiler error -// normalize-stderr-test "internal compiler error.*" -> "" -// normalize-stderr-test "DefId\([^)]*\)" -> "..." -// normalize-stderr-test "\nerror: internal compiler error.*\n\n" -> "" -// normalize-stderr-test "note:.*unexpectedly panicked.*\n\n" -> "" -// normalize-stderr-test "note: we would appreciate a bug report.*\n\n" -> "" -// normalize-stderr-test "note: compiler flags.*\n\n" -> "" -// normalize-stderr-test "note: rustc.*running on.*\n\n" -> "" -// normalize-stderr-test "thread.*panicked.*:\n.*\n" -> "" -// normalize-stderr-test "stack backtrace:\n" -> "" -// normalize-stderr-test "\s\d{1,}: .*\n" -> "" -// normalize-stderr-test "\s at .*\n" -> "" -// normalize-stderr-test ".*note: Some details.*\n" -> "" -// normalize-stderr-test "\n[ ]*\n" -> "" -// normalize-stderr-test "compiler/.*: projection" -> "projection" -// normalize-stderr-test ".*omitted \d{1,} frame.*\n" -> "" -// normalize-stderr-test "error: [\s\n]*query stack during panic:\n" -> "" -// this should run-pass +// see comment on `tests/ui/const-generics/late-bound-vars/simple.rs` #![feature(generic_const_exprs)] #![allow(incomplete_features)] diff --git a/tests/ui/const-generics/late-bound-vars/in_closure.stderr b/tests/ui/const-generics/late-bound-vars/in_closure.stderr index ac406bf2bb1..e15496454a0 100644 --- a/tests/ui/const-generics/late-bound-vars/in_closure.stderr +++ b/tests/ui/const-generics/late-bound-vars/in_closure.stderr @@ -1,10 +1,20 @@ -#0 [mir_borrowck] borrow-checking `test::{closure#0}::{constant#1}` -#1 [mir_drops_elaborated_and_const_checked] elaborating drops for `test::{closure#0}::{constant#1}` -#2 [mir_for_ctfe] caching mir of `test::{closure#0}::{constant#1}` for CTFE -#3 [eval_to_allocation_raw] const-evaluating + checking `test::{closure#0}::{constant#1}` -#4 [eval_to_allocation_raw] const-evaluating + checking `test::{closure#0}::{constant#1}` -#5 [eval_to_valtree] evaluating type-level constant -#6 [typeck] type-checking `test` -#7 [analysis] running analysis passes on this crate -end of query stack -error: aborting due to previous error \ No newline at end of file +error: cannot capture late-bound lifetime in constant + --> $DIR/in_closure.rs:16:29 + | +LL | fn test<'a>() { + | -- lifetime defined here +LL | let _ = || { +LL | let _: [u8; inner::<'a>()]; + | ^^ + +error: cannot capture late-bound lifetime in constant + --> $DIR/in_closure.rs:17:29 + | +LL | fn test<'a>() { + | -- lifetime defined here +... +LL | let _ = [0; inner::<'a>()]; + | ^^ + +error: aborting due to 2 previous errors + diff --git a/tests/ui/const-generics/late-bound-vars/late-bound-in-return-issue-77357.rs b/tests/ui/const-generics/late-bound-vars/late-bound-in-return-issue-77357.rs new file mode 100644 index 00000000000..b81aa50d9a9 --- /dev/null +++ b/tests/ui/const-generics/late-bound-vars/late-bound-in-return-issue-77357.rs @@ -0,0 +1,13 @@ +// known-bug: unknown +// see comment on `tests/ui/const-generics/late-bound-vars/simple.rs` + +#![feature(generic_const_exprs)] +#![allow(incomplete_features)] + +trait MyTrait<T> {} + +fn bug<'a, T>() -> &'static dyn MyTrait<[(); { |x: &'a u32| { x }; 4 }]> { + todo!() +} + +fn main() {} diff --git a/tests/ui/const-generics/late-bound-vars/late-bound-in-return-issue-77357.stderr b/tests/ui/const-generics/late-bound-vars/late-bound-in-return-issue-77357.stderr new file mode 100644 index 00000000000..21c8fe6865c --- /dev/null +++ b/tests/ui/const-generics/late-bound-vars/late-bound-in-return-issue-77357.stderr @@ -0,0 +1,8 @@ +error: cannot capture late-bound lifetime in constant + --> $DIR/late-bound-in-return-issue-77357.rs:9:53 + | +LL | fn bug<'a, T>() -> &'static dyn MyTrait<[(); { |x: &'a u32| { x }; 4 }]> { + | -- lifetime defined here ^^ + +error: aborting due to previous error + diff --git a/tests/ui/const-generics/late-bound-vars/late-bound-in-where-issue-83993.rs b/tests/ui/const-generics/late-bound-vars/late-bound-in-where-issue-83993.rs new file mode 100644 index 00000000000..89f01748fc9 --- /dev/null +++ b/tests/ui/const-generics/late-bound-vars/late-bound-in-where-issue-83993.rs @@ -0,0 +1,15 @@ +// known-bug: unknown +// see comment on `tests/ui/const-generics/late-bound-vars/simple.rs` + +#![feature(generic_const_exprs)] +#![allow(incomplete_features)] + +fn bug<'a>() +where + for<'b> [(); { + let x: &'b (); + 0 + }]: +{} + +fn main() {} diff --git a/tests/ui/const-generics/late-bound-vars/late-bound-in-where-issue-83993.stderr b/tests/ui/const-generics/late-bound-vars/late-bound-in-where-issue-83993.stderr new file mode 100644 index 00000000000..a66dc8db914 --- /dev/null +++ b/tests/ui/const-generics/late-bound-vars/late-bound-in-where-issue-83993.stderr @@ -0,0 +1,10 @@ +error: cannot capture late-bound lifetime in constant + --> $DIR/late-bound-in-where-issue-83993.rs:10:17 + | +LL | for<'b> [(); { + | -- lifetime defined here +LL | let x: &'b (); + | ^^ + +error: aborting due to previous error + diff --git a/tests/ui/const-generics/late-bound-vars/simple.rs b/tests/ui/const-generics/late-bound-vars/simple.rs index 544073b5a56..a562bd8cb41 100644 --- a/tests/ui/const-generics/late-bound-vars/simple.rs +++ b/tests/ui/const-generics/late-bound-vars/simple.rs @@ -1,22 +1,13 @@ -// failure-status: 101 // known-bug: unknown -// error-pattern:internal compiler error -// normalize-stderr-test "internal compiler error.*" -> "" -// normalize-stderr-test "DefId\([^)]*\)" -> "..." -// normalize-stderr-test "\nerror: internal compiler error.*\n\n" -> "" -// normalize-stderr-test "note:.*unexpectedly panicked.*\n\n" -> "" -// normalize-stderr-test "note: we would appreciate a bug report.*\n\n" -> "" -// normalize-stderr-test "note: compiler flags.*\n\n" -> "" -// normalize-stderr-test "note: rustc.*running on.*\n\n" -> "" -// normalize-stderr-test "thread.*panicked.*:\n.*\n" -> "" -// normalize-stderr-test "stack backtrace:\n" -> "" -// normalize-stderr-test "\s\d{1,}: .*\n" -> "" -// normalize-stderr-test "\s at .*\n" -> "" -// normalize-stderr-test ".*note: Some details.*\n" -> "" -// normalize-stderr-test "\n\n[ ]*\n" -> "" -// normalize-stderr-test "compiler/.*: projection" -> "projection" -// normalize-stderr-test ".*omitted \d{1,} frame.*\n" -> "" -// normalize-stderr-test "error: [\s\n]*query stack" -> "error: query stack" + +// If we want this to compile, then we'd need to do something like RPITs do, +// where nested associated constants have early-bound versions of their captured +// late-bound vars inserted into their generics. This gives us substitutable +// lifetimes to actually use when borrow-checking the associated const, which is +// lowered as a totally separate body from its parent. Since this doesn't exist, +// we should just error rather than resolving this late-bound var with no +// binder to actually attach it to, or worse, as a free region that can't even be +// substituted correctly, and ICEing. - @compiler-errors #![feature(generic_const_exprs)] #![allow(incomplete_features)] diff --git a/tests/ui/const-generics/late-bound-vars/simple.stderr b/tests/ui/const-generics/late-bound-vars/simple.stderr index c9f2164b635..e72e373630d 100644 --- a/tests/ui/const-generics/late-bound-vars/simple.stderr +++ b/tests/ui/const-generics/late-bound-vars/simple.stderr @@ -1,12 +1,19 @@ -error: query stack during panic: -#0 [mir_borrowck] borrow-checking `test::{constant#1}` -#1 [mir_drops_elaborated_and_const_checked] elaborating drops for `test::{constant#1}` -#2 [mir_for_ctfe] caching mir of `test::{constant#1}` for CTFE -#3 [eval_to_allocation_raw] const-evaluating + checking `test::{constant#1}` -#4 [eval_to_allocation_raw] const-evaluating + checking `test::{constant#1}` -#5 [eval_to_valtree] evaluating type-level constant -#6 [typeck] type-checking `test` -#7 [analysis] running analysis passes on this crate -end of query stack -error: aborting due to previous error +error: cannot capture late-bound lifetime in constant + --> $DIR/simple.rs:20:25 + | +LL | fn test<'a>() { + | -- lifetime defined here +LL | let _: [u8; inner::<'a>()]; + | ^^ + +error: cannot capture late-bound lifetime in constant + --> $DIR/simple.rs:21:25 + | +LL | fn test<'a>() { + | -- lifetime defined here +LL | let _: [u8; inner::<'a>()]; +LL | let _ = [0; inner::<'a>()]; + | ^^ + +error: aborting due to 2 previous errors diff --git a/tests/ui/const_prop/dont-propagate-generic-instance-2.rs b/tests/ui/const_prop/dont-propagate-generic-instance-2.rs new file mode 100644 index 00000000000..e5525af23f0 --- /dev/null +++ b/tests/ui/const_prop/dont-propagate-generic-instance-2.rs @@ -0,0 +1,26 @@ +// run-pass + +#![feature(inline_const)] + +// Makes sure we don't propagate generic instances of `Self: ?Sized` blanket impls. +// This is relevant when we have an overlapping impl and builtin dyn instance. +// See <https://github.com/rust-lang/rust/pull/114941> for more context. + +trait Trait { + fn foo(&self) -> &'static str; +} + +impl<T: ?Sized> Trait for T { + fn foo(&self) -> &'static str { + std::any::type_name::<T>() + } +} + +fn bar<T: ?Sized>() -> fn(&T) -> &'static str { + const { Trait::foo as fn(&T) -> &'static str } + // If const prop were to propagate the instance +} + +fn main() { + assert_eq!("i32", bar::<dyn Trait>()(&1i32)); +} diff --git a/tests/ui/const_prop/dont-propagate-generic-instance.rs b/tests/ui/const_prop/dont-propagate-generic-instance.rs new file mode 100644 index 00000000000..5994961b887 --- /dev/null +++ b/tests/ui/const_prop/dont-propagate-generic-instance.rs @@ -0,0 +1,24 @@ +// run-pass + +// Makes sure we don't propagate generic instances of `Self: ?Sized` blanket impls. +// This is relevant when we have an overlapping impl and builtin dyn instance. +// See <https://github.com/rust-lang/rust/pull/114941> for more context. + +trait Trait { + fn foo(&self) -> &'static str; +} + +impl<T: ?Sized> Trait for T { + fn foo(&self) -> &'static str { + std::any::type_name::<T>() + } +} + +const fn bar<T: ?Sized>() -> fn(&T) -> &'static str { + Trait::foo + // If const prop were to propagate the instance +} + +fn main() { + assert_eq!("i32", bar::<dyn Trait>()(&1i32)); +} diff --git a/tests/ui/consts/const-err-late.stderr b/tests/ui/consts/const-err-late.stderr index 149d3b5236b..85bc56baed8 100644 --- a/tests/ui/consts/const-err-late.stderr +++ b/tests/ui/consts/const-err-late.stderr @@ -4,7 +4,7 @@ error[E0080]: evaluation of `S::<i32>::FOO` failed LL | const FOO: u8 = [5u8][1]; | ^^^^^^^^ index out of bounds: the length is 1 but the index is 1 -note: erroneous constant used +note: erroneous constant encountered --> $DIR/const-err-late.rs:19:16 | LL | black_box((S::<i32>::FOO, S::<u32>::FOO)); @@ -16,13 +16,13 @@ error[E0080]: evaluation of `S::<u32>::FOO` failed LL | const FOO: u8 = [5u8][1]; | ^^^^^^^^ index out of bounds: the length is 1 but the index is 1 -note: erroneous constant used +note: erroneous constant encountered --> $DIR/const-err-late.rs:19:31 | LL | black_box((S::<i32>::FOO, S::<u32>::FOO)); | ^^^^^^^^^^^^^ -note: erroneous constant used +note: erroneous constant encountered --> $DIR/const-err-late.rs:19:16 | LL | black_box((S::<i32>::FOO, S::<u32>::FOO)); diff --git a/tests/ui/consts/const-err-multi.stderr b/tests/ui/consts/const-err-multi.stderr index 28af8e5eb09..1ad504b3a80 100644 --- a/tests/ui/consts/const-err-multi.stderr +++ b/tests/ui/consts/const-err-multi.stderr @@ -4,19 +4,19 @@ error[E0080]: evaluation of constant value failed LL | pub const A: i8 = -i8::MIN; | ^^^^^^^^ attempt to negate `i8::MIN`, which would overflow -note: erroneous constant used +note: erroneous constant encountered --> $DIR/const-err-multi.rs:3:19 | LL | pub const B: i8 = A; | ^ -note: erroneous constant used +note: erroneous constant encountered --> $DIR/const-err-multi.rs:5:19 | LL | pub const C: u8 = A as u8; | ^ -note: erroneous constant used +note: erroneous constant encountered --> $DIR/const-err-multi.rs:7:24 | LL | pub const D: i8 = 50 - A; diff --git a/tests/ui/consts/const-eval/erroneous-const.stderr b/tests/ui/consts/const-eval/erroneous-const.stderr index 770f95062ab..0e31520fdbb 100644 --- a/tests/ui/consts/const-eval/erroneous-const.stderr +++ b/tests/ui/consts/const-eval/erroneous-const.stderr @@ -4,7 +4,7 @@ error[E0080]: evaluation of `PrintName::<i32>::VOID` failed LL | const VOID: () = [()][2]; | ^^^^^^^ index out of bounds: the length is 1 but the index is 2 -note: erroneous constant used +note: erroneous constant encountered --> $DIR/erroneous-const.rs:13:13 | LL | PrintName::<T>::VOID; diff --git a/tests/ui/consts/const-eval/erroneous-const2.stderr b/tests/ui/consts/const-eval/erroneous-const2.stderr index 082c2876575..4ca44694cd7 100644 --- a/tests/ui/consts/const-eval/erroneous-const2.stderr +++ b/tests/ui/consts/const-eval/erroneous-const2.stderr @@ -4,7 +4,7 @@ error[E0080]: evaluation of `PrintName::<i32>::VOID` failed LL | const VOID: () = [()][2]; | ^^^^^^^ index out of bounds: the length is 1 but the index is 2 -note: erroneous constant used +note: erroneous constant encountered --> $DIR/erroneous-const2.rs:13:9 | LL | PrintName::<i32>::VOID; diff --git a/tests/ui/consts/const-eval/issue-44578.stderr b/tests/ui/consts/const-eval/issue-44578.stderr index f3952809e4b..c7aaee94271 100644 --- a/tests/ui/consts/const-eval/issue-44578.stderr +++ b/tests/ui/consts/const-eval/issue-44578.stderr @@ -4,13 +4,13 @@ error[E0080]: evaluation of `<Bar<u16, u8> as Foo>::AMT` failed LL | const AMT: usize = [A::AMT][(A::AMT > B::AMT) as usize]; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ index out of bounds: the length is 1 but the index is 1 -note: erroneous constant used +note: erroneous constant encountered --> $DIR/issue-44578.rs:25:20 | LL | println!("{}", <Bar<u16, u8> as Foo>::AMT); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ -note: erroneous constant used +note: erroneous constant encountered --> $DIR/issue-44578.rs:25:20 | LL | println!("{}", <Bar<u16, u8> as Foo>::AMT); @@ -18,7 +18,7 @@ LL | println!("{}", <Bar<u16, u8> as Foo>::AMT); | = note: this note originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info) -note: erroneous constant used +note: erroneous constant encountered --> $DIR/issue-44578.rs:25:20 | LL | println!("{}", <Bar<u16, u8> as Foo>::AMT); diff --git a/tests/ui/consts/const-eval/issue-50814-2.stderr b/tests/ui/consts/const-eval/issue-50814-2.stderr index 956f7aec9da..450fb002373 100644 --- a/tests/ui/consts/const-eval/issue-50814-2.stderr +++ b/tests/ui/consts/const-eval/issue-50814-2.stderr @@ -4,7 +4,7 @@ error[E0080]: evaluation of `<A<()> as Foo<()>>::BAR` failed LL | const BAR: usize = [5, 6, 7][T::BOO]; | ^^^^^^^^^^^^^^^^^ index out of bounds: the length is 3 but the index is 42 -note: erroneous constant used +note: erroneous constant encountered --> $DIR/issue-50814-2.rs:18:6 | LL | &<A<T> as Foo<T>>::BAR diff --git a/tests/ui/consts/const-eval/issue-50814.stderr b/tests/ui/consts/const-eval/issue-50814.stderr index 05b6271f4e4..48a20d0bbd0 100644 --- a/tests/ui/consts/const-eval/issue-50814.stderr +++ b/tests/ui/consts/const-eval/issue-50814.stderr @@ -4,7 +4,7 @@ error[E0080]: evaluation of `<Sum<U8, U8> as Unsigned>::MAX` failed LL | const MAX: u8 = A::MAX + B::MAX; | ^^^^^^^^^^^^^^^ attempt to compute `u8::MAX + u8::MAX`, which would overflow -note: erroneous constant used +note: erroneous constant encountered --> $DIR/issue-50814.rs:20:6 | LL | &Sum::<U8, U8>::MAX diff --git a/tests/ui/consts/const-eval/panic-assoc-never-type.rs b/tests/ui/consts/const-eval/panic-assoc-never-type.rs index 1abe708d19e..88ce5b0d895 100644 --- a/tests/ui/consts/const-eval/panic-assoc-never-type.rs +++ b/tests/ui/consts/const-eval/panic-assoc-never-type.rs @@ -11,5 +11,5 @@ impl PrintName { } fn main() { - let _ = PrintName::VOID; //~ erroneous constant used + let _ = PrintName::VOID; //~ erroneous constant encountered } diff --git a/tests/ui/consts/const-eval/panic-assoc-never-type.stderr b/tests/ui/consts/const-eval/panic-assoc-never-type.stderr index 7c36a3a426e..4706497dbc4 100644 --- a/tests/ui/consts/const-eval/panic-assoc-never-type.stderr +++ b/tests/ui/consts/const-eval/panic-assoc-never-type.stderr @@ -6,13 +6,13 @@ LL | const VOID: ! = panic!(); | = note: this error originates in the macro `$crate::panic::panic_2015` which comes from the expansion of the macro `panic` (in Nightly builds, run with -Z macro-backtrace for more info) -note: erroneous constant used +note: erroneous constant encountered --> $DIR/panic-assoc-never-type.rs:14:13 | LL | let _ = PrintName::VOID; | ^^^^^^^^^^^^^^^ -note: erroneous constant used +note: erroneous constant encountered --> $DIR/panic-assoc-never-type.rs:14:13 | LL | let _ = PrintName::VOID; diff --git a/tests/ui/consts/const-eval/raw-bytes.32bit.stderr b/tests/ui/consts/const-eval/raw-bytes.32bit.stderr index e087a0ebec7..042e7eeb31e 100644 --- a/tests/ui/consts/const-eval/raw-bytes.32bit.stderr +++ b/tests/ui/consts/const-eval/raw-bytes.32bit.stderr @@ -341,7 +341,7 @@ LL | const SLICE_CONTENT_INVALID: &[bool] = &[unsafe { mem::transmute(3u8) }]; ╾ALLOC_ID╼ │ ╾──╼ } -note: erroneous constant used +note: erroneous constant encountered --> $DIR/raw-bytes.rs:160:40 | LL | const SLICE_CONTENT_INVALID: &[bool] = &[unsafe { mem::transmute(3u8) }]; @@ -358,7 +358,7 @@ LL | const MYSLICE_PREFIX_BAD: &MySliceBool = &MySlice(unsafe { mem::transmute(3 ╾ALLOC_ID╼ │ ╾──╼ } -note: erroneous constant used +note: erroneous constant encountered --> $DIR/raw-bytes.rs:166:42 | LL | const MYSLICE_PREFIX_BAD: &MySliceBool = &MySlice(unsafe { mem::transmute(3u8) }, [false]); @@ -375,7 +375,7 @@ LL | const MYSLICE_SUFFIX_BAD: &MySliceBool = &MySlice(true, [unsafe { mem::tran ╾ALLOC_ID╼ │ ╾──╼ } -note: erroneous constant used +note: erroneous constant encountered --> $DIR/raw-bytes.rs:170:42 | LL | const MYSLICE_SUFFIX_BAD: &MySliceBool = &MySlice(true, [unsafe { mem::transmute(3u8) }]); diff --git a/tests/ui/consts/const-eval/raw-bytes.64bit.stderr b/tests/ui/consts/const-eval/raw-bytes.64bit.stderr index 4c655161f79..8426a95055c 100644 --- a/tests/ui/consts/const-eval/raw-bytes.64bit.stderr +++ b/tests/ui/consts/const-eval/raw-bytes.64bit.stderr @@ -341,7 +341,7 @@ LL | const SLICE_CONTENT_INVALID: &[bool] = &[unsafe { mem::transmute(3u8) }]; ╾ALLOC_ID╼ │ ╾──────╼ } -note: erroneous constant used +note: erroneous constant encountered --> $DIR/raw-bytes.rs:160:40 | LL | const SLICE_CONTENT_INVALID: &[bool] = &[unsafe { mem::transmute(3u8) }]; @@ -358,7 +358,7 @@ LL | const MYSLICE_PREFIX_BAD: &MySliceBool = &MySlice(unsafe { mem::transmute(3 ╾ALLOC_ID╼ │ ╾──────╼ } -note: erroneous constant used +note: erroneous constant encountered --> $DIR/raw-bytes.rs:166:42 | LL | const MYSLICE_PREFIX_BAD: &MySliceBool = &MySlice(unsafe { mem::transmute(3u8) }, [false]); @@ -375,7 +375,7 @@ LL | const MYSLICE_SUFFIX_BAD: &MySliceBool = &MySlice(true, [unsafe { mem::tran ╾ALLOC_ID╼ │ ╾──────╼ } -note: erroneous constant used +note: erroneous constant encountered --> $DIR/raw-bytes.rs:170:42 | LL | const MYSLICE_SUFFIX_BAD: &MySliceBool = &MySlice(true, [unsafe { mem::transmute(3u8) }]); diff --git a/tests/ui/consts/const-eval/ub-ref-ptr.stderr b/tests/ui/consts/const-eval/ub-ref-ptr.stderr index 0ee1e60877f..6d5c36cea7d 100644 --- a/tests/ui/consts/const-eval/ub-ref-ptr.stderr +++ b/tests/ui/consts/const-eval/ub-ref-ptr.stderr @@ -60,7 +60,7 @@ LL | const REF_AS_USIZE_SLICE: &[usize] = &[unsafe { mem::transmute(&0) }]; = help: this code performed an operation that depends on the underlying bytes representing a pointer = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported -note: erroneous constant used +note: erroneous constant encountered --> $DIR/ub-ref-ptr.rs:36:38 | LL | const REF_AS_USIZE_SLICE: &[usize] = &[unsafe { mem::transmute(&0) }]; @@ -75,7 +75,7 @@ LL | const REF_AS_USIZE_BOX_SLICE: Box<[usize]> = unsafe { mem::transmute::<&[us = help: this code performed an operation that depends on the underlying bytes representing a pointer = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported -note: erroneous constant used +note: erroneous constant encountered --> $DIR/ub-ref-ptr.rs:39:85 | LL | const REF_AS_USIZE_BOX_SLICE: Box<[usize]> = unsafe { mem::transmute::<&[usize], _>(&[mem::transmute(&0)]) }; diff --git a/tests/ui/consts/const-eval/ub-wide-ptr.stderr b/tests/ui/consts/const-eval/ub-wide-ptr.stderr index 02bbbf50435..d8add67fac1 100644 --- a/tests/ui/consts/const-eval/ub-wide-ptr.stderr +++ b/tests/ui/consts/const-eval/ub-wide-ptr.stderr @@ -139,7 +139,7 @@ LL | const SLICE_CONTENT_INVALID: &[bool] = &[unsafe { mem::transmute(3u8) }]; HEX_DUMP } -note: erroneous constant used +note: erroneous constant encountered --> $DIR/ub-wide-ptr.rs:85:40 | LL | const SLICE_CONTENT_INVALID: &[bool] = &[unsafe { mem::transmute(3u8) }]; @@ -156,7 +156,7 @@ LL | const MYSLICE_PREFIX_BAD: &MySliceBool = &MySlice(unsafe { mem::transmute(3 HEX_DUMP } -note: erroneous constant used +note: erroneous constant encountered --> $DIR/ub-wide-ptr.rs:92:42 | LL | const MYSLICE_PREFIX_BAD: &MySliceBool = &MySlice(unsafe { mem::transmute(3u8) }, [false]); @@ -173,7 +173,7 @@ LL | const MYSLICE_SUFFIX_BAD: &MySliceBool = &MySlice(true, [unsafe { mem::tran HEX_DUMP } -note: erroneous constant used +note: erroneous constant encountered --> $DIR/ub-wide-ptr.rs:96:42 | LL | const MYSLICE_SUFFIX_BAD: &MySliceBool = &MySlice(true, [unsafe { mem::transmute(3u8) }]); diff --git a/tests/ui/consts/const-eval/union-const-eval-field.stderr b/tests/ui/consts/const-eval/union-const-eval-field.stderr index 9899c56c0ec..ce260300fc8 100644 --- a/tests/ui/consts/const-eval/union-const-eval-field.stderr +++ b/tests/ui/consts/const-eval/union-const-eval-field.stderr @@ -4,13 +4,13 @@ error[E0080]: evaluation of constant value failed LL | const FIELD3: Field3 = unsafe { UNION.field3 }; | ^^^^^^^^^^^^ using uninitialized data, but this operation requires initialized memory -note: erroneous constant used +note: erroneous constant encountered --> $DIR/union-const-eval-field.rs:31:5 | LL | FIELD3 | ^^^^^^ -note: erroneous constant used +note: erroneous constant encountered --> $DIR/union-const-eval-field.rs:31:5 | LL | FIELD3 diff --git a/tests/ui/consts/const-float-bits-reject-conv.stderr b/tests/ui/consts/const-float-bits-reject-conv.stderr index 7ad02252094..1511dab12b0 100644 --- a/tests/ui/consts/const-float-bits-reject-conv.stderr +++ b/tests/ui/consts/const-float-bits-reject-conv.stderr @@ -30,25 +30,25 @@ LL | const MASKED_NAN2: u32 = f32::NAN.to_bits() ^ 0x0055_5555; | ^^^^^^^^^^^^^^^^^^ = note: this error originates in the macro `$crate::panic::panic_2021` which comes from the expansion of the macro `panic` (in Nightly builds, run with -Z macro-backtrace for more info) -note: erroneous constant used +note: erroneous constant encountered --> $DIR/const-float-bits-reject-conv.rs:35:34 | LL | const_assert!(f32::from_bits(MASKED_NAN1).is_nan()); | ^^^^^^^^^^^ -note: erroneous constant used +note: erroneous constant encountered --> $DIR/const-float-bits-reject-conv.rs:36:34 | LL | const_assert!(f32::from_bits(MASKED_NAN1).is_nan()); | ^^^^^^^^^^^ -note: erroneous constant used +note: erroneous constant encountered --> $DIR/const-float-bits-reject-conv.rs:42:34 | LL | const_assert!(f32::from_bits(MASKED_NAN1).to_bits(), MASKED_NAN1); | ^^^^^^^^^^^ -note: erroneous constant used +note: erroneous constant encountered --> $DIR/const-float-bits-reject-conv.rs:43:34 | LL | const_assert!(f32::from_bits(MASKED_NAN2).to_bits(), MASKED_NAN2); @@ -86,25 +86,25 @@ LL | const MASKED_NAN2: u64 = f64::NAN.to_bits() ^ 0x0005_5555_5555_5555; | ^^^^^^^^^^^^^^^^^^ = note: this error originates in the macro `$crate::panic::panic_2021` which comes from the expansion of the macro `panic` (in Nightly builds, run with -Z macro-backtrace for more info) -note: erroneous constant used +note: erroneous constant encountered --> $DIR/const-float-bits-reject-conv.rs:57:34 | LL | const_assert!(f64::from_bits(MASKED_NAN1).is_nan()); | ^^^^^^^^^^^ -note: erroneous constant used +note: erroneous constant encountered --> $DIR/const-float-bits-reject-conv.rs:58:34 | LL | const_assert!(f64::from_bits(MASKED_NAN1).is_nan()); | ^^^^^^^^^^^ -note: erroneous constant used +note: erroneous constant encountered --> $DIR/const-float-bits-reject-conv.rs:61:34 | LL | const_assert!(f64::from_bits(MASKED_NAN1).to_bits(), MASKED_NAN1); | ^^^^^^^^^^^ -note: erroneous constant used +note: erroneous constant encountered --> $DIR/const-float-bits-reject-conv.rs:62:34 | LL | const_assert!(f64::from_bits(MASKED_NAN2).to_bits(), MASKED_NAN2); diff --git a/tests/ui/consts/const-len-underflow-separate-spans.next.stderr b/tests/ui/consts/const-len-underflow-separate-spans.next.stderr index d9208d0706a..b7b5b648c12 100644 --- a/tests/ui/consts/const-len-underflow-separate-spans.next.stderr +++ b/tests/ui/consts/const-len-underflow-separate-spans.next.stderr @@ -4,7 +4,7 @@ error[E0080]: evaluation of constant value failed LL | const LEN: usize = ONE - TWO; | ^^^^^^^^^ attempt to compute `1_usize - 2_usize`, which would overflow -note: erroneous constant used +note: erroneous constant encountered --> $DIR/const-len-underflow-separate-spans.rs:14:17 | LL | let a: [i8; LEN] = unimplemented!(); diff --git a/tests/ui/consts/const-len-underflow-separate-spans.old.stderr b/tests/ui/consts/const-len-underflow-separate-spans.old.stderr index d9208d0706a..b7b5b648c12 100644 --- a/tests/ui/consts/const-len-underflow-separate-spans.old.stderr +++ b/tests/ui/consts/const-len-underflow-separate-spans.old.stderr @@ -4,7 +4,7 @@ error[E0080]: evaluation of constant value failed LL | const LEN: usize = ONE - TWO; | ^^^^^^^^^ attempt to compute `1_usize - 2_usize`, which would overflow -note: erroneous constant used +note: erroneous constant encountered --> $DIR/const-len-underflow-separate-spans.rs:14:17 | LL | let a: [i8; LEN] = unimplemented!(); diff --git a/tests/ui/consts/escaping-bound-var.rs b/tests/ui/consts/escaping-bound-var.rs new file mode 100644 index 00000000000..7c1fbd24f55 --- /dev/null +++ b/tests/ui/consts/escaping-bound-var.rs @@ -0,0 +1,13 @@ +#![feature(generic_const_exprs)] +//~^ WARN the feature `generic_const_exprs` is incomplete + +fn test<'a>( + _: &'a (), +) -> [(); { + let x: &'a (); + //~^ ERROR cannot capture late-bound lifetime in constant + 1 +}] { +} + +fn main() {} diff --git a/tests/ui/consts/escaping-bound-var.stderr b/tests/ui/consts/escaping-bound-var.stderr new file mode 100644 index 00000000000..d26ae2cee1c --- /dev/null +++ b/tests/ui/consts/escaping-bound-var.stderr @@ -0,0 +1,20 @@ +warning: the feature `generic_const_exprs` is incomplete and may not be safe to use and/or cause compiler crashes + --> $DIR/escaping-bound-var.rs:1:12 + | +LL | #![feature(generic_const_exprs)] + | ^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #76560 <https://github.com/rust-lang/rust/issues/76560> for more information + = note: `#[warn(incomplete_features)]` on by default + +error: cannot capture late-bound lifetime in constant + --> $DIR/escaping-bound-var.rs:7:13 + | +LL | fn test<'a>( + | -- lifetime defined here +... +LL | let x: &'a (); + | ^^ + +error: aborting due to previous error; 1 warning emitted + diff --git a/tests/ui/consts/invalid-union.32bit.stderr b/tests/ui/consts/invalid-union.32bit.stderr index 0dd18a55786..b6cf060e5ae 100644 --- a/tests/ui/consts/invalid-union.32bit.stderr +++ b/tests/ui/consts/invalid-union.32bit.stderr @@ -9,13 +9,13 @@ LL | fn main() { ╾─alloc7──╼ │ ╾──╼ } -note: erroneous constant used +note: erroneous constant encountered --> $DIR/invalid-union.rs:43:25 | LL | let _: &'static _ = &C; | ^^ -note: erroneous constant used +note: erroneous constant encountered --> $DIR/invalid-union.rs:43:25 | LL | let _: &'static _ = &C; diff --git a/tests/ui/consts/invalid-union.64bit.stderr b/tests/ui/consts/invalid-union.64bit.stderr index 07f36ee2832..e3a3ef62c4a 100644 --- a/tests/ui/consts/invalid-union.64bit.stderr +++ b/tests/ui/consts/invalid-union.64bit.stderr @@ -9,13 +9,13 @@ LL | fn main() { ╾───────alloc7────────╼ │ ╾──────╼ } -note: erroneous constant used +note: erroneous constant encountered --> $DIR/invalid-union.rs:43:25 | LL | let _: &'static _ = &C; | ^^ -note: erroneous constant used +note: erroneous constant encountered --> $DIR/invalid-union.rs:43:25 | LL | let _: &'static _ = &C; diff --git a/tests/ui/consts/issue-105536-const-val-roundtrip-ptr-eq.rs b/tests/ui/consts/issue-105536-const-val-roundtrip-ptr-eq.rs new file mode 100644 index 00000000000..1615399be32 --- /dev/null +++ b/tests/ui/consts/issue-105536-const-val-roundtrip-ptr-eq.rs @@ -0,0 +1,31 @@ +// run-pass + +// This does not reflect a stable guarantee (we guarantee very little for equality of pointers +// around `const`), but it would be good to understand what is happening if these assertions ever +// fail. +use std::ptr::NonNull; +use std::slice::from_raw_parts; + +const PTR_U8: *const u8 = NonNull::dangling().as_ptr(); +const CONST_U8_REF: &[u8] = unsafe { from_raw_parts(PTR_U8, 0) }; +const CONST_U8_PTR: *const u8 = unsafe { from_raw_parts(PTR_U8, 0).as_ptr() }; +static STATIC_U8_REF: &[u8] = unsafe { from_raw_parts(PTR_U8, 0) }; + +const PTR_U16: *const u16 = NonNull::dangling().as_ptr(); +const CONST_U16_REF: &[u16] = unsafe { from_raw_parts(PTR_U16, 0) }; + +const fn const_u8_fn() -> &'static [u8] { + unsafe { from_raw_parts(PTR_U8, 0) } +} + +fn main() { + let ptr_u8 = unsafe { from_raw_parts(PTR_U8, 0) }.as_ptr(); + let ptr_u16 = unsafe { from_raw_parts(PTR_U16, 0) }.as_ptr(); + + assert_eq!(ptr_u8, PTR_U8); + assert_eq!(ptr_u8, CONST_U8_PTR); + assert_eq!(ptr_u8, const_u8_fn().as_ptr()); + assert_eq!(ptr_u8, STATIC_U8_REF.as_ptr()); + assert_eq!(ptr_u16, CONST_U16_REF.as_ptr()); + assert_eq!(ptr_u8, CONST_U8_REF.as_ptr()); +} diff --git a/tests/ui/consts/issue-36163.stderr b/tests/ui/consts/issue-36163.stderr index 190b41062f8..6fcfe3ed28c 100644 --- a/tests/ui/consts/issue-36163.stderr +++ b/tests/ui/consts/issue-36163.stderr @@ -1,15 +1,25 @@ -error[E0391]: cycle detected when const-evaluating + checking `Foo::B::{constant#0}` +error[E0391]: cycle detected when simplifying constant for the type system `Foo::B::{constant#0}` --> $DIR/issue-36163.rs:4:9 | LL | B = A, | ^ | +note: ...which requires const-evaluating + checking `Foo::B::{constant#0}`... + --> $DIR/issue-36163.rs:4:9 + | +LL | B = A, + | ^ +note: ...which requires simplifying constant for the type system `A`... + --> $DIR/issue-36163.rs:1:1 + | +LL | const A: isize = Foo::B as isize; + | ^^^^^^^^^^^^^^ note: ...which requires const-evaluating + checking `A`... --> $DIR/issue-36163.rs:1:18 | LL | const A: isize = Foo::B as isize; | ^^^^^^^^^^^^^^^ - = note: ...which again requires const-evaluating + checking `Foo::B::{constant#0}`, completing the cycle + = note: ...which again requires simplifying constant for the type system `Foo::B::{constant#0}`, completing the cycle note: cycle used when simplifying constant for the type system `Foo::B::{constant#0}` --> $DIR/issue-36163.rs:4:9 | diff --git a/tests/ui/consts/miri_unleashed/assoc_const.stderr b/tests/ui/consts/miri_unleashed/assoc_const.stderr index d97097d352a..274b1de7e7d 100644 --- a/tests/ui/consts/miri_unleashed/assoc_const.stderr +++ b/tests/ui/consts/miri_unleashed/assoc_const.stderr @@ -13,13 +13,13 @@ note: inside `<String as Bar<Vec<u32>, String>>::F` LL | const F: u32 = (U::X, 42).1; | ^ -note: erroneous constant used +note: erroneous constant encountered --> $DIR/assoc_const.rs:29:13 | LL | let y = <String as Bar<Vec<u32>, String>>::F; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -note: erroneous constant used +note: erroneous constant encountered --> $DIR/assoc_const.rs:29:13 | LL | let y = <String as Bar<Vec<u32>, String>>::F; diff --git a/tests/ui/consts/miri_unleashed/assoc_const_2.stderr b/tests/ui/consts/miri_unleashed/assoc_const_2.stderr index ae7b03fc9dd..c8e4cab4e71 100644 --- a/tests/ui/consts/miri_unleashed/assoc_const_2.stderr +++ b/tests/ui/consts/miri_unleashed/assoc_const_2.stderr @@ -4,13 +4,13 @@ error[E0080]: evaluation of `<std::string::String as Bar<std::string::String>>:: LL | const F: u32 = 100 / U::X; | ^^^^^^^^^^ attempt to divide `100_u32` by zero -note: erroneous constant used +note: erroneous constant encountered --> $DIR/assoc_const_2.rs:27:13 | LL | let y = <String as Bar<String>>::F; | ^^^^^^^^^^^^^^^^^^^^^^^^^^ -note: erroneous constant used +note: erroneous constant encountered --> $DIR/assoc_const_2.rs:27:13 | LL | let y = <String as Bar<String>>::F; diff --git a/tests/ui/consts/uninhabited-const-issue-61744.stderr b/tests/ui/consts/uninhabited-const-issue-61744.stderr index adefbf336c2..f48e6c4ce51 100644 --- a/tests/ui/consts/uninhabited-const-issue-61744.stderr +++ b/tests/ui/consts/uninhabited-const-issue-61744.stderr @@ -645,13 +645,13 @@ note: inside `<i32 as Const>::CONSTANT` LL | const CONSTANT: i32 = unsafe { fake_type() }; | ^^^^^^^^^^^ -note: erroneous constant used +note: erroneous constant encountered --> $DIR/uninhabited-const-issue-61744.rs:18:10 | LL | dbg!(i32::CONSTANT); | ^^^^^^^^^^^^^ -note: erroneous constant used +note: erroneous constant encountered --> $DIR/uninhabited-const-issue-61744.rs:18:10 | LL | dbg!(i32::CONSTANT); diff --git a/tests/ui/cross/cross-fn-cache-hole.stderr b/tests/ui/cross/cross-fn-cache-hole.stderr index 7e15562b081..79d1713934b 100644 --- a/tests/ui/cross/cross-fn-cache-hole.stderr +++ b/tests/ui/cross/cross-fn-cache-hole.stderr @@ -4,6 +4,11 @@ error[E0277]: the trait bound `i32: Bar<u32>` is not satisfied LL | where i32: Foo<u32, A> | ^^^^^^^^^^^^^^^^ the trait `Bar<u32>` is not implemented for `i32` | +help: this trait has no implementations, consider adding one + --> $DIR/cross-fn-cache-hole.rs:11:1 + | +LL | trait Bar<X> { } + | ^^^^^^^^^^^^ = help: see issue #48214 = help: add `#![feature(trivial_bounds)]` to the crate attributes to enable diff --git a/tests/ui/deriving/deriving-all-codegen.stdout b/tests/ui/deriving/deriving-all-codegen.stdout index 6bfc859bfe8..3d9f8129d93 100644 --- a/tests/ui/deriving/deriving-all-codegen.stdout +++ b/tests/ui/deriving/deriving-all-codegen.stdout @@ -60,7 +60,7 @@ impl ::core::marker::StructuralEq for Empty { } impl ::core::cmp::Eq for Empty { #[inline] #[doc(hidden)] - #[no_coverage] + #[coverage(off)] fn assert_receiver_is_total_eq(&self) -> () {} } #[automatically_derived] @@ -135,7 +135,7 @@ impl ::core::marker::StructuralEq for Point { } impl ::core::cmp::Eq for Point { #[inline] #[doc(hidden)] - #[no_coverage] + #[coverage(off)] fn assert_receiver_is_total_eq(&self) -> () { let _: ::core::cmp::AssertParamIsEq<u32>; } @@ -221,7 +221,7 @@ impl ::core::marker::StructuralEq for PackedPoint { } impl ::core::cmp::Eq for PackedPoint { #[inline] #[doc(hidden)] - #[no_coverage] + #[coverage(off)] fn assert_receiver_is_total_eq(&self) -> () { let _: ::core::cmp::AssertParamIsEq<u32>; } @@ -334,7 +334,7 @@ impl ::core::marker::StructuralEq for Big { } impl ::core::cmp::Eq for Big { #[inline] #[doc(hidden)] - #[no_coverage] + #[coverage(off)] fn assert_receiver_is_total_eq(&self) -> () { let _: ::core::cmp::AssertParamIsEq<u32>; } @@ -500,7 +500,7 @@ impl ::core::marker::StructuralEq for Unsized { } impl ::core::cmp::Eq for Unsized { #[inline] #[doc(hidden)] - #[no_coverage] + #[coverage(off)] fn assert_receiver_is_total_eq(&self) -> () { let _: ::core::cmp::AssertParamIsEq<[u32]>; } @@ -615,7 +615,7 @@ impl<T: ::core::cmp::Eq + Trait, U: ::core::cmp::Eq> ::core::cmp::Eq for Generic<T, U> where T::A: ::core::cmp::Eq { #[inline] #[doc(hidden)] - #[no_coverage] + #[coverage(off)] fn assert_receiver_is_total_eq(&self) -> () { let _: ::core::cmp::AssertParamIsEq<T>; let _: ::core::cmp::AssertParamIsEq<T::A>; @@ -738,7 +738,7 @@ impl<T: ::core::cmp::Eq + ::core::marker::Copy + Trait, U: ::core::cmp::Eq + T::A: ::core::cmp::Eq + ::core::marker::Copy { #[inline] #[doc(hidden)] - #[no_coverage] + #[coverage(off)] fn assert_receiver_is_total_eq(&self) -> () { let _: ::core::cmp::AssertParamIsEq<T>; let _: ::core::cmp::AssertParamIsEq<T::A>; @@ -821,7 +821,7 @@ impl ::core::marker::StructuralEq for Enum0 { } impl ::core::cmp::Eq for Enum0 { #[inline] #[doc(hidden)] - #[no_coverage] + #[coverage(off)] fn assert_receiver_is_total_eq(&self) -> () {} } #[automatically_derived] @@ -892,7 +892,7 @@ impl ::core::marker::StructuralEq for Enum1 { } impl ::core::cmp::Eq for Enum1 { #[inline] #[doc(hidden)] - #[no_coverage] + #[coverage(off)] fn assert_receiver_is_total_eq(&self) -> () { let _: ::core::cmp::AssertParamIsEq<u32>; } @@ -959,7 +959,7 @@ impl ::core::marker::StructuralEq for Fieldless1 { } impl ::core::cmp::Eq for Fieldless1 { #[inline] #[doc(hidden)] - #[no_coverage] + #[coverage(off)] fn assert_receiver_is_total_eq(&self) -> () {} } #[automatically_derived] @@ -1034,7 +1034,7 @@ impl ::core::marker::StructuralEq for Fieldless { } impl ::core::cmp::Eq for Fieldless { #[inline] #[doc(hidden)] - #[no_coverage] + #[coverage(off)] fn assert_receiver_is_total_eq(&self) -> () {} } #[automatically_derived] @@ -1142,7 +1142,7 @@ impl ::core::marker::StructuralEq for Mixed { } impl ::core::cmp::Eq for Mixed { #[inline] #[doc(hidden)] - #[no_coverage] + #[coverage(off)] fn assert_receiver_is_total_eq(&self) -> () { let _: ::core::cmp::AssertParamIsEq<u32>; let _: ::core::cmp::AssertParamIsEq<Option<u32>>; @@ -1270,7 +1270,7 @@ impl ::core::marker::StructuralEq for Fielded { } impl ::core::cmp::Eq for Fielded { #[inline] #[doc(hidden)] - #[no_coverage] + #[coverage(off)] fn assert_receiver_is_total_eq(&self) -> () { let _: ::core::cmp::AssertParamIsEq<u32>; let _: ::core::cmp::AssertParamIsEq<bool>; @@ -1393,7 +1393,7 @@ impl<T: ::core::cmp::Eq, U: ::core::cmp::Eq> ::core::cmp::Eq for EnumGeneric<T, U> { #[inline] #[doc(hidden)] - #[no_coverage] + #[coverage(off)] fn assert_receiver_is_total_eq(&self) -> () { let _: ::core::cmp::AssertParamIsEq<T>; let _: ::core::cmp::AssertParamIsEq<U>; diff --git a/tests/ui/diagnostic_namespace/feature-gate-diagnostic_namespace.rs b/tests/ui/diagnostic_namespace/feature-gate-diagnostic_namespace.rs index a686ed9c84e..b08e291621f 100644 --- a/tests/ui/diagnostic_namespace/feature-gate-diagnostic_namespace.rs +++ b/tests/ui/diagnostic_namespace/feature-gate-diagnostic_namespace.rs @@ -1,12 +1,12 @@ #[diagnostic::non_existing_attribute] //~^ERROR `#[diagnostic]` attribute name space is experimental [E0658] -//~|WARNING unknown diagnostic attribute [unknown_diagnostic_attributes] +//~|WARNING unknown diagnostic attribute [unknown_or_malformed_diagnostic_attributes] pub trait Bar { } #[diagnostic::non_existing_attribute(with_option = "foo")] //~^ERROR `#[diagnostic]` attribute name space is experimental [E0658] -//~|WARNING unknown diagnostic attribute [unknown_diagnostic_attributes] +//~|WARNING unknown diagnostic attribute [unknown_or_malformed_diagnostic_attributes] struct Foo; fn main() { diff --git a/tests/ui/diagnostic_namespace/feature-gate-diagnostic_namespace.stderr b/tests/ui/diagnostic_namespace/feature-gate-diagnostic_namespace.stderr index 45c95cbb3c7..017d00e2c8e 100644 --- a/tests/ui/diagnostic_namespace/feature-gate-diagnostic_namespace.stderr +++ b/tests/ui/diagnostic_namespace/feature-gate-diagnostic_namespace.stderr @@ -4,7 +4,7 @@ error[E0658]: `#[diagnostic]` attribute name space is experimental LL | #[diagnostic::non_existing_attribute] | ^^^^^^^^^^ | - = note: see issue #94785 <https://github.com/rust-lang/rust/issues/94785> for more information + = note: see issue #111996 <https://github.com/rust-lang/rust/issues/111996> for more information = help: add `#![feature(diagnostic_namespace)]` to the crate attributes to enable error[E0658]: `#[diagnostic]` attribute name space is experimental @@ -13,7 +13,7 @@ error[E0658]: `#[diagnostic]` attribute name space is experimental LL | #[diagnostic::non_existing_attribute(with_option = "foo")] | ^^^^^^^^^^ | - = note: see issue #94785 <https://github.com/rust-lang/rust/issues/94785> for more information + = note: see issue #111996 <https://github.com/rust-lang/rust/issues/111996> for more information = help: add `#![feature(diagnostic_namespace)]` to the crate attributes to enable warning: unknown diagnostic attribute @@ -22,7 +22,7 @@ warning: unknown diagnostic attribute LL | #[diagnostic::non_existing_attribute] | ^^^^^^^^^^^^^^^^^^^^^^ | - = note: `#[warn(unknown_diagnostic_attributes)]` on by default + = note: `#[warn(unknown_or_malformed_diagnostic_attributes)]` on by default warning: unknown diagnostic attribute --> $DIR/feature-gate-diagnostic_namespace.rs:7:15 diff --git a/tests/ui/diagnostic_namespace/non_existing_attributes_accepted.stderr b/tests/ui/diagnostic_namespace/non_existing_attributes_accepted.stderr index 4f9b7ba2bcf..753077b365e 100644 --- a/tests/ui/diagnostic_namespace/non_existing_attributes_accepted.stderr +++ b/tests/ui/diagnostic_namespace/non_existing_attributes_accepted.stderr @@ -4,7 +4,7 @@ warning: unknown diagnostic attribute LL | #[diagnostic::non_existing_attribute] | ^^^^^^^^^^^^^^^^^^^^^^ | - = note: `#[warn(unknown_diagnostic_attributes)]` on by default + = note: `#[warn(unknown_or_malformed_diagnostic_attributes)]` on by default warning: unknown diagnostic attribute --> $DIR/non_existing_attributes_accepted.rs:8:15 diff --git a/tests/ui/diagnostic_namespace/on_unimplemented/do_not_fail_parsing_on_invalid_options_1.rs b/tests/ui/diagnostic_namespace/on_unimplemented/do_not_fail_parsing_on_invalid_options_1.rs new file mode 100644 index 00000000000..00fb59d14d7 --- /dev/null +++ b/tests/ui/diagnostic_namespace/on_unimplemented/do_not_fail_parsing_on_invalid_options_1.rs @@ -0,0 +1,37 @@ +#![feature(diagnostic_namespace)] + +#[diagnostic::on_unimplemented(unsupported = "foo")] +//~^WARN malformed `on_unimplemented` attribute +//~|WARN malformed `on_unimplemented` attribute +trait Foo {} + +#[diagnostic::on_unimplemented(message = "Baz")] +//~^WARN `#[diagnostic::on_unimplemented]` can only be applied to trait definitions +struct Bar {} + +#[diagnostic::on_unimplemented(message = "Boom", unsupported = "Bar")] +//~^WARN malformed `on_unimplemented` attribute +//~|WARN malformed `on_unimplemented` attribute +trait Baz {} + +#[diagnostic::on_unimplemented(message = "Boom", on(_Self = "i32", message = "whatever"))] +//~^WARN malformed `on_unimplemented` attribute +//~|WARN malformed `on_unimplemented` attribute +trait Boom {} + +#[diagnostic::on_unimplemented = "boom"] +//~^WARN malformed `on_unimplemented` attribute +trait Doom {} + +fn take_foo(_: impl Foo) {} +fn take_baz(_: impl Baz) {} +fn take_boom(_: impl Boom) {} + +fn main() { + take_foo(1_i32); + //~^ERROR the trait bound `i32: Foo` is not satisfied + take_baz(1_i32); + //~^ERROR Boom + take_boom(1_i32); + //~^ERROR Boom +} diff --git a/tests/ui/diagnostic_namespace/on_unimplemented/do_not_fail_parsing_on_invalid_options_1.stderr b/tests/ui/diagnostic_namespace/on_unimplemented/do_not_fail_parsing_on_invalid_options_1.stderr new file mode 100644 index 00000000000..bb1b29ef248 --- /dev/null +++ b/tests/ui/diagnostic_namespace/on_unimplemented/do_not_fail_parsing_on_invalid_options_1.stderr @@ -0,0 +1,110 @@ +warning: `#[diagnostic::on_unimplemented]` can only be applied to trait definitions + --> $DIR/do_not_fail_parsing_on_invalid_options_1.rs:8:1 + | +LL | #[diagnostic::on_unimplemented(message = "Baz")] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: `#[warn(unknown_or_malformed_diagnostic_attributes)]` on by default + +warning: malformed `on_unimplemented` attribute + --> $DIR/do_not_fail_parsing_on_invalid_options_1.rs:3:32 + | +LL | #[diagnostic::on_unimplemented(unsupported = "foo")] + | ^^^^^^^^^^^^^^^^^^^ + +warning: malformed `on_unimplemented` attribute + --> $DIR/do_not_fail_parsing_on_invalid_options_1.rs:12:50 + | +LL | #[diagnostic::on_unimplemented(message = "Boom", unsupported = "Bar")] + | ^^^^^^^^^^^^^^^^^^^ + +warning: malformed `on_unimplemented` attribute + --> $DIR/do_not_fail_parsing_on_invalid_options_1.rs:17:50 + | +LL | #[diagnostic::on_unimplemented(message = "Boom", on(_Self = "i32", message = "whatever"))] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +warning: malformed `on_unimplemented` attribute + --> $DIR/do_not_fail_parsing_on_invalid_options_1.rs:22:1 + | +LL | #[diagnostic::on_unimplemented = "boom"] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +warning: malformed `on_unimplemented` attribute + --> $DIR/do_not_fail_parsing_on_invalid_options_1.rs:3:32 + | +LL | #[diagnostic::on_unimplemented(unsupported = "foo")] + | ^^^^^^^^^^^^^^^^^^^ + +error[E0277]: the trait bound `i32: Foo` is not satisfied + --> $DIR/do_not_fail_parsing_on_invalid_options_1.rs:31:14 + | +LL | take_foo(1_i32); + | -------- ^^^^^ the trait `Foo` is not implemented for `i32` + | | + | required by a bound introduced by this call + | +help: this trait has no implementations, consider adding one + --> $DIR/do_not_fail_parsing_on_invalid_options_1.rs:6:1 + | +LL | trait Foo {} + | ^^^^^^^^^ +note: required by a bound in `take_foo` + --> $DIR/do_not_fail_parsing_on_invalid_options_1.rs:26:21 + | +LL | fn take_foo(_: impl Foo) {} + | ^^^ required by this bound in `take_foo` + +warning: malformed `on_unimplemented` attribute + --> $DIR/do_not_fail_parsing_on_invalid_options_1.rs:12:50 + | +LL | #[diagnostic::on_unimplemented(message = "Boom", unsupported = "Bar")] + | ^^^^^^^^^^^^^^^^^^^ + +error[E0277]: Boom + --> $DIR/do_not_fail_parsing_on_invalid_options_1.rs:33:14 + | +LL | take_baz(1_i32); + | -------- ^^^^^ the trait `Baz` is not implemented for `i32` + | | + | required by a bound introduced by this call + | +help: this trait has no implementations, consider adding one + --> $DIR/do_not_fail_parsing_on_invalid_options_1.rs:15:1 + | +LL | trait Baz {} + | ^^^^^^^^^ +note: required by a bound in `take_baz` + --> $DIR/do_not_fail_parsing_on_invalid_options_1.rs:27:21 + | +LL | fn take_baz(_: impl Baz) {} + | ^^^ required by this bound in `take_baz` + +warning: malformed `on_unimplemented` attribute + --> $DIR/do_not_fail_parsing_on_invalid_options_1.rs:17:50 + | +LL | #[diagnostic::on_unimplemented(message = "Boom", on(_Self = "i32", message = "whatever"))] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error[E0277]: Boom + --> $DIR/do_not_fail_parsing_on_invalid_options_1.rs:35:15 + | +LL | take_boom(1_i32); + | --------- ^^^^^ the trait `Boom` is not implemented for `i32` + | | + | required by a bound introduced by this call + | +help: this trait has no implementations, consider adding one + --> $DIR/do_not_fail_parsing_on_invalid_options_1.rs:20:1 + | +LL | trait Boom {} + | ^^^^^^^^^^ +note: required by a bound in `take_boom` + --> $DIR/do_not_fail_parsing_on_invalid_options_1.rs:28:22 + | +LL | fn take_boom(_: impl Boom) {} + | ^^^^ required by this bound in `take_boom` + +error: aborting due to 3 previous errors; 8 warnings emitted + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/diagnostic_namespace/on_unimplemented/feature-gate-diagnostic_on_unimplemented.rs b/tests/ui/diagnostic_namespace/on_unimplemented/feature-gate-diagnostic_on_unimplemented.rs new file mode 100644 index 00000000000..609a840c118 --- /dev/null +++ b/tests/ui/diagnostic_namespace/on_unimplemented/feature-gate-diagnostic_on_unimplemented.rs @@ -0,0 +1,7 @@ +#[diagnostic::on_unimplemented(message = "Foo")] +//~^ERROR `#[diagnostic]` attribute name space is experimental [E0658] +pub trait Bar { +} + +fn main() { +} diff --git a/tests/ui/diagnostic_namespace/on_unimplemented/feature-gate-diagnostic_on_unimplemented.stderr b/tests/ui/diagnostic_namespace/on_unimplemented/feature-gate-diagnostic_on_unimplemented.stderr new file mode 100644 index 00000000000..21f02e3a73b --- /dev/null +++ b/tests/ui/diagnostic_namespace/on_unimplemented/feature-gate-diagnostic_on_unimplemented.stderr @@ -0,0 +1,12 @@ +error[E0658]: `#[diagnostic]` attribute name space is experimental + --> $DIR/feature-gate-diagnostic_on_unimplemented.rs:1:3 + | +LL | #[diagnostic::on_unimplemented(message = "Foo")] + | ^^^^^^^^^^ + | + = note: see issue #111996 <https://github.com/rust-lang/rust/issues/111996> for more information + = help: add `#![feature(diagnostic_namespace)]` to the crate attributes to enable + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0658`. diff --git a/tests/ui/diagnostic_namespace/on_unimplemented/on_unimplemented_simple.rs b/tests/ui/diagnostic_namespace/on_unimplemented/on_unimplemented_simple.rs new file mode 100644 index 00000000000..797edbc9ec5 --- /dev/null +++ b/tests/ui/diagnostic_namespace/on_unimplemented/on_unimplemented_simple.rs @@ -0,0 +1,11 @@ +#![feature(diagnostic_namespace)] + +#[diagnostic::on_unimplemented(message = "Foo", label = "Bar", note = "Baz")] +trait Foo {} + +fn takes_foo(_: impl Foo) {} + +fn main() { + takes_foo(()); + //~^ERROR Foo +} diff --git a/tests/ui/diagnostic_namespace/on_unimplemented/on_unimplemented_simple.stderr b/tests/ui/diagnostic_namespace/on_unimplemented/on_unimplemented_simple.stderr new file mode 100644 index 00000000000..549c7caa720 --- /dev/null +++ b/tests/ui/diagnostic_namespace/on_unimplemented/on_unimplemented_simple.stderr @@ -0,0 +1,24 @@ +error[E0277]: Foo + --> $DIR/on_unimplemented_simple.rs:9:15 + | +LL | takes_foo(()); + | --------- ^^ Bar + | | + | required by a bound introduced by this call + | + = help: the trait `Foo` is not implemented for `()` + = note: Baz +help: this trait has no implementations, consider adding one + --> $DIR/on_unimplemented_simple.rs:4:1 + | +LL | trait Foo {} + | ^^^^^^^^^ +note: required by a bound in `takes_foo` + --> $DIR/on_unimplemented_simple.rs:6:22 + | +LL | fn takes_foo(_: impl Foo) {} + | ^^^ required by this bound in `takes_foo` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/drop/dynamic-drop.rs b/tests/ui/drop/dynamic-drop.rs index 9e51d3adaaa..caef6358ea7 100644 --- a/tests/ui/drop/dynamic-drop.rs +++ b/tests/ui/drop/dynamic-drop.rs @@ -2,6 +2,7 @@ // needs-unwind #![feature(generators, generator_trait)] +#![feature(if_let_guard)] #![allow(unused_assignments)] #![allow(unused_variables)] @@ -332,6 +333,16 @@ fn move_ref_pattern(a: &Allocator) { let (ref _a, ref mut _b, _c, mut _d) = tup; } +fn if_let_guard(a: &Allocator, c: bool, d: i32) { + let foo = if c { Some(a.alloc()) } else { None }; + + match d == 0 { + false if let Some(a) = foo => { let b = a; } + true if let true = { drop(foo.unwrap_or_else(|| a.alloc())); d == 1 } => {} + _ => {} + } +} + fn panic_after_return(a: &Allocator) -> Ptr<'_> { // Panic in the drop of `p` or `q` can leak let exceptions = vec![8, 9]; @@ -497,6 +508,13 @@ fn main() { run_test(|a| move_ref_pattern(a)); + run_test(|a| if_let_guard(a, true, 0)); + run_test(|a| if_let_guard(a, true, 1)); + run_test(|a| if_let_guard(a, true, 2)); + run_test(|a| if_let_guard(a, false, 0)); + run_test(|a| if_let_guard(a, false, 1)); + run_test(|a| if_let_guard(a, false, 2)); + run_test(|a| { panic_after_return(a); }); diff --git a/tests/ui/dst/dst-bad-coerce1.stderr b/tests/ui/dst/dst-bad-coerce1.stderr index 2c75518c298..455d15e935f 100644 --- a/tests/ui/dst/dst-bad-coerce1.stderr +++ b/tests/ui/dst/dst-bad-coerce1.stderr @@ -15,6 +15,11 @@ error[E0277]: the trait bound `Foo: Bar` is not satisfied LL | let f3: &Fat<dyn Bar> = f2; | ^^ the trait `Bar` is not implemented for `Foo` | +help: this trait has no implementations, consider adding one + --> $DIR/dst-bad-coerce1.rs:10:1 + | +LL | trait Bar { fn bar(&self) {} } + | ^^^^^^^^^ = note: required for the cast from `&Fat<Foo>` to `&Fat<dyn Bar>` error[E0308]: mismatched types @@ -34,6 +39,11 @@ error[E0277]: the trait bound `Foo: Bar` is not satisfied LL | let f3: &(dyn Bar,) = f2; | ^^ the trait `Bar` is not implemented for `Foo` | +help: this trait has no implementations, consider adding one + --> $DIR/dst-bad-coerce1.rs:10:1 + | +LL | trait Bar { fn bar(&self) {} } + | ^^^^^^^^^ = note: required for the cast from `&(Foo,)` to `&(dyn Bar,)` error: aborting due to 4 previous errors diff --git a/tests/ui/dyn-star/error.stderr b/tests/ui/dyn-star/error.stderr index ae54b9ca707..e039bb6f1c8 100644 --- a/tests/ui/dyn-star/error.stderr +++ b/tests/ui/dyn-star/error.stderr @@ -3,6 +3,12 @@ error[E0277]: the trait bound `{integer}: Foo` is not satisfied | LL | let dyn_i: dyn* Foo = i; | ^ the trait `Foo` is not implemented for `{integer}` + | +help: this trait has no implementations, consider adding one + --> $DIR/error.rs:6:1 + | +LL | trait Foo {} + | ^^^^^^^^^ error: aborting due to previous error diff --git a/tests/ui/error-codes/E0040.stderr b/tests/ui/error-codes/E0040.stderr index 9fcda1a9385..839be79d28d 100644 --- a/tests/ui/error-codes/E0040.stderr +++ b/tests/ui/error-codes/E0040.stderr @@ -2,10 +2,12 @@ error[E0040]: explicit use of destructor method --> $DIR/E0040.rs:16:7 | LL | x.drop(); - | --^^^^-- - | | | - | | explicit destructor calls not allowed - | help: consider using `drop` function: `drop(x)` + | ^^^^ explicit destructor calls not allowed + | +help: consider using `drop` function + | +LL | drop(x); + | +++++ ~ error: aborting due to previous error diff --git a/tests/ui/error-codes/E0054.stderr b/tests/ui/error-codes/E0054.stderr index 6b1092760fb..0a4adabbaf6 100644 --- a/tests/ui/error-codes/E0054.stderr +++ b/tests/ui/error-codes/E0054.stderr @@ -1,8 +1,13 @@ -error[E0054]: cannot cast as `bool` +error[E0054]: cannot cast `i32` as `bool` --> $DIR/E0054.rs:3:24 | LL | let x_is_nonzero = x as bool; - | ^^^^^^^^^ help: compare with zero instead: `x != 0` + | ^^^^^^^^^ + | +help: compare with zero instead + | +LL | let x_is_nonzero = x != 0; + | ~~~~ error: aborting due to previous error diff --git a/tests/ui/error-codes/E0277.stderr b/tests/ui/error-codes/E0277.stderr index 440e43dff81..0b0d2b09720 100644 --- a/tests/ui/error-codes/E0277.stderr +++ b/tests/ui/error-codes/E0277.stderr @@ -21,6 +21,11 @@ LL | some_func(5i32); | | | required by a bound introduced by this call | +help: this trait has no implementations, consider adding one + --> $DIR/E0277.rs:3:1 + | +LL | trait Foo { + | ^^^^^^^^^ note: required by a bound in `some_func` --> $DIR/E0277.rs:7:17 | diff --git a/tests/ui/error-codes/E0401.stderr b/tests/ui/error-codes/E0401.stderr index fa4b91cacef..928c8d11d20 100644 --- a/tests/ui/error-codes/E0401.stderr +++ b/tests/ui/error-codes/E0401.stderr @@ -1,26 +1,26 @@ -error[E0401]: can't use generic parameters from outer function +error[E0401]: can't use generic parameters from outer item --> $DIR/E0401.rs:4:39 | LL | fn foo<T>(x: T) { - | - type parameter from outer function + | - type parameter from outer item LL | fn bfnr<U, V: Baz<U>, W: Fn()>(y: T) { - | - ^ use of generic parameter from outer function + | - ^ use of generic parameter from outer item | | - | help: try using a local generic parameter instead: `T,` + | help: try introducing a local generic parameter here: `T,` -error[E0401]: can't use generic parameters from outer function +error[E0401]: can't use generic parameters from outer item --> $DIR/E0401.rs:9:16 | LL | fn foo<T>(x: T) { - | - type parameter from outer function + | - type parameter from outer item ... LL | fn baz<U, - | - help: try using a local generic parameter instead: `T,` + | - help: try introducing a local generic parameter here: `T,` ... LL | (y: T) { - | ^ use of generic parameter from outer function + | ^ use of generic parameter from outer item -error[E0401]: can't use generic parameters from outer function +error[E0401]: can't use generic parameters from outer item --> $DIR/E0401.rs:24:25 | LL | impl<T> Iterator for A<T> { @@ -29,8 +29,8 @@ LL | impl<T> Iterator for A<T> { LL | fn helper(sel: &Self) -> u8 { | ^^^^ | | - | use of generic parameter from outer function - | use a type here instead + | use of generic parameter from outer item + | refer to the type directly here instead error[E0282]: type annotations needed --> $DIR/E0401.rs:11:5 diff --git a/tests/ui/error-festival.stderr b/tests/ui/error-festival.stderr index e8ee1d96942..9d75671c4e6 100644 --- a/tests/ui/error-festival.stderr +++ b/tests/ui/error-festival.stderr @@ -59,11 +59,16 @@ error[E0605]: non-primitive cast: `u8` as `Vec<u8>` LL | x as Vec<u8>; | ^^^^^^^^^^^^ an `as` expression can only be used to convert between primitive types or to coerce to a specific trait object -error[E0054]: cannot cast as `bool` +error[E0054]: cannot cast `{integer}` as `bool` --> $DIR/error-festival.rs:33:24 | LL | let x_is_nonzero = x as bool; - | ^^^^^^^^^ help: compare with zero instead: `x != 0` + | ^^^^^^^^^ + | +help: compare with zero instead + | +LL | let x_is_nonzero = x != 0; + | ~~~~ error[E0606]: casting `&u8` as `u32` is invalid --> $DIR/error-festival.rs:37:18 diff --git a/tests/ui/explicit/explicit-call-to-dtor.stderr b/tests/ui/explicit/explicit-call-to-dtor.stderr index f3c9bf6cccd..f2e0b73b6c5 100644 --- a/tests/ui/explicit/explicit-call-to-dtor.stderr +++ b/tests/ui/explicit/explicit-call-to-dtor.stderr @@ -2,10 +2,12 @@ error[E0040]: explicit use of destructor method --> $DIR/explicit-call-to-dtor.rs:15:7 | LL | x.drop(); - | --^^^^-- - | | | - | | explicit destructor calls not allowed - | help: consider using `drop` function: `drop(x)` + | ^^^^ explicit destructor calls not allowed + | +help: consider using `drop` function + | +LL | drop(x); + | +++++ ~ error: aborting due to previous error diff --git a/tests/ui/explicit/explicit-call-to-supertrait-dtor.stderr b/tests/ui/explicit/explicit-call-to-supertrait-dtor.stderr index c7067117349..5fa42fcf191 100644 --- a/tests/ui/explicit/explicit-call-to-supertrait-dtor.stderr +++ b/tests/ui/explicit/explicit-call-to-supertrait-dtor.stderr @@ -2,10 +2,12 @@ error[E0040]: explicit use of destructor method --> $DIR/explicit-call-to-supertrait-dtor.rs:22:14 | LL | self.drop(); - | -----^^^^-- - | | | - | | explicit destructor calls not allowed - | help: consider using `drop` function: `drop(self)` + | ^^^^ explicit destructor calls not allowed + | +help: consider using `drop` function + | +LL | drop(self); + | +++++ ~ error: aborting due to previous error diff --git a/tests/ui/expr/if/bad-if-let-suggestion.rs b/tests/ui/expr/if/bad-if-let-suggestion.rs index a8b2a283039..99d584ac7a5 100644 --- a/tests/ui/expr/if/bad-if-let-suggestion.rs +++ b/tests/ui/expr/if/bad-if-let-suggestion.rs @@ -4,9 +4,8 @@ fn a() { if let x = 1 && i = 2 {} //~^ ERROR cannot find value `i` in this scope - //~| ERROR `let` expressions in this position are unstable //~| ERROR mismatched types - //~| ERROR `let` expressions are not supported here + //~| ERROR expected expression, found `let` statement } fn b() { diff --git a/tests/ui/expr/if/bad-if-let-suggestion.stderr b/tests/ui/expr/if/bad-if-let-suggestion.stderr index 3a53a20b453..20ac9ca76ba 100644 --- a/tests/ui/expr/if/bad-if-let-suggestion.stderr +++ b/tests/ui/expr/if/bad-if-let-suggestion.stderr @@ -1,4 +1,4 @@ -error: `let` expressions are not supported here +error: expected expression, found `let` statement --> $DIR/bad-if-let-suggestion.rs:5:8 | LL | if let x = 1 && i = 2 {} @@ -13,7 +13,7 @@ LL | if let x = 1 && i = 2 {} | ^ not found in this scope error[E0425]: cannot find value `i` in this scope - --> $DIR/bad-if-let-suggestion.rs:13:9 + --> $DIR/bad-if-let-suggestion.rs:12:9 | LL | fn a() { | ------ similarly named function `a` defined here @@ -22,7 +22,7 @@ LL | if (i + j) = i {} | ^ help: a function with a similar name exists: `a` error[E0425]: cannot find value `j` in this scope - --> $DIR/bad-if-let-suggestion.rs:13:13 + --> $DIR/bad-if-let-suggestion.rs:12:13 | LL | fn a() { | ------ similarly named function `a` defined here @@ -31,7 +31,7 @@ LL | if (i + j) = i {} | ^ help: a function with a similar name exists: `a` error[E0425]: cannot find value `i` in this scope - --> $DIR/bad-if-let-suggestion.rs:13:18 + --> $DIR/bad-if-let-suggestion.rs:12:18 | LL | fn a() { | ------ similarly named function `a` defined here @@ -40,7 +40,7 @@ LL | if (i + j) = i {} | ^ help: a function with a similar name exists: `a` error[E0425]: cannot find value `x` in this scope - --> $DIR/bad-if-let-suggestion.rs:20:8 + --> $DIR/bad-if-let-suggestion.rs:19:8 | LL | fn a() { | ------ similarly named function `a` defined here @@ -48,15 +48,6 @@ LL | fn a() { LL | if x[0] = 1 {} | ^ help: a function with a similar name exists: `a` -error[E0658]: `let` expressions in this position are unstable - --> $DIR/bad-if-let-suggestion.rs:5:8 - | -LL | if let x = 1 && i = 2 {} - | ^^^^^^^^^ - | - = note: see issue #53667 <https://github.com/rust-lang/rust/issues/53667> for more information - = help: add `#![feature(let_chains)]` to the crate attributes to enable - error[E0308]: mismatched types --> $DIR/bad-if-let-suggestion.rs:5:8 | @@ -68,7 +59,7 @@ help: you might have meant to compare for equality LL | if let x = 1 && i == 2 {} | + -error: aborting due to 8 previous errors +error: aborting due to 7 previous errors -Some errors have detailed explanations: E0308, E0425, E0658. +Some errors have detailed explanations: E0308, E0425. For more information about an error, try `rustc --explain E0308`. diff --git a/tests/ui/feature-gates/feature-gate-coverage-attribute.rs b/tests/ui/feature-gates/feature-gate-coverage-attribute.rs new file mode 100644 index 00000000000..0a463755f13 --- /dev/null +++ b/tests/ui/feature-gates/feature-gate-coverage-attribute.rs @@ -0,0 +1,14 @@ +#![crate_type = "lib"] +#![feature(no_coverage)] //~ ERROR feature has been removed [E0557] + +#[derive(PartialEq, Eq)] // ensure deriving `Eq` does not enable `feature(coverage)` +struct Foo { + a: u8, + b: u32, +} + +#[coverage(off)] //~ ERROR the `#[coverage]` attribute is an experimental feature +fn requires_feature_coverage() -> bool { + let bar = Foo { a: 0, b: 0 }; + bar == Foo { a: 0, b: 0 } +} diff --git a/tests/ui/feature-gates/feature-gate-coverage-attribute.stderr b/tests/ui/feature-gates/feature-gate-coverage-attribute.stderr new file mode 100644 index 00000000000..0131a19a39d --- /dev/null +++ b/tests/ui/feature-gates/feature-gate-coverage-attribute.stderr @@ -0,0 +1,21 @@ +error[E0557]: feature has been removed + --> $DIR/feature-gate-coverage-attribute.rs:2:12 + | +LL | #![feature(no_coverage)] + | ^^^^^^^^^^^ feature has been removed + | + = note: renamed to `coverage_attribute` + +error[E0658]: the `#[coverage]` attribute is an experimental feature + --> $DIR/feature-gate-coverage-attribute.rs:10:1 + | +LL | #[coverage(off)] + | ^^^^^^^^^^^^^^^^ + | + = note: see issue #84605 <https://github.com/rust-lang/rust/issues/84605> for more information + = help: add `#![feature(coverage_attribute)]` to the crate attributes to enable + +error: aborting due to 2 previous errors + +Some errors have detailed explanations: E0557, E0658. +For more information about an error, try `rustc --explain E0557`. diff --git a/tests/ui/feature-gates/feature-gate-no_coverage.rs b/tests/ui/feature-gates/feature-gate-no_coverage.rs deleted file mode 100644 index fd4c6f76059..00000000000 --- a/tests/ui/feature-gates/feature-gate-no_coverage.rs +++ /dev/null @@ -1,13 +0,0 @@ -#![crate_type = "lib"] - -#[derive(PartialEq, Eq)] // ensure deriving `Eq` does not enable `feature(no_coverage)` -struct Foo { - a: u8, - b: u32, -} - -#[no_coverage] //~ ERROR the `#[no_coverage]` attribute is an experimental feature -fn requires_feature_no_coverage() -> bool { - let bar = Foo { a: 0, b: 0 }; - bar == Foo { a: 0, b: 0 } -} diff --git a/tests/ui/feature-gates/feature-gate-no_coverage.stderr b/tests/ui/feature-gates/feature-gate-no_coverage.stderr deleted file mode 100644 index f7167e0b771..00000000000 --- a/tests/ui/feature-gates/feature-gate-no_coverage.stderr +++ /dev/null @@ -1,12 +0,0 @@ -error[E0658]: the `#[no_coverage]` attribute is an experimental feature - --> $DIR/feature-gate-no_coverage.rs:9:1 - | -LL | #[no_coverage] - | ^^^^^^^^^^^^^^ - | - = note: see issue #84605 <https://github.com/rust-lang/rust/issues/84605> for more information - = help: add `#![feature(no_coverage)]` to the crate attributes to enable - -error: aborting due to previous error - -For more information about this error, try `rustc --explain E0658`. diff --git a/tests/ui/fmt/raw-idents.rs b/tests/ui/fmt/raw-idents.rs new file mode 100644 index 00000000000..29a74c55a4a --- /dev/null +++ b/tests/ui/fmt/raw-idents.rs @@ -0,0 +1,17 @@ +// Regression test for https://github.com/rust-lang/rust/issues/115466 + +// The "identifier" in format strings is parsed as an IDENTIFIER_OR_KEYWORD, not an IDENTIFIER. +// Test that there is an actionable diagnostic if a RAW_IDENTIFIER is used instead. + +fn main() { + let r#type = "foobar"; + println!("It is {r#type}"); //~ ERROR: invalid format string: raw identifiers are not supported + println!(r##"It still is {r#type}"##); //~ ERROR: invalid format string: raw identifiers are not supported + println!(concat!("{r#", "type}")); //~ ERROR: invalid format string: raw identifiers are not supported + println!("{\x72\x23type:?}"); //~ ERROR: invalid format string: raw identifiers are not supported + + // OK + println!("{type}"); + println!("{let}", let = r#type); + println!("{let}", r#let = r#type); +} diff --git a/tests/ui/fmt/raw-idents.stderr b/tests/ui/fmt/raw-idents.stderr new file mode 100644 index 00000000000..2ddc114d286 --- /dev/null +++ b/tests/ui/fmt/raw-idents.stderr @@ -0,0 +1,44 @@ +error: invalid format string: raw identifiers are not supported + --> $DIR/raw-idents.rs:8:22 + | +LL | println!("It is {r#type}"); + | --^^^^ + | | + | raw identifier used here in format string + | help: remove the `r#` + | + = note: identifiers in format strings can be keywords and don't need to be prefixed with `r#` + +error: invalid format string: raw identifiers are not supported + --> $DIR/raw-idents.rs:9:31 + | +LL | println!(r##"It still is {r#type}"##); + | --^^^^ + | | + | raw identifier used here in format string + | help: remove the `r#` + | + = note: identifiers in format strings can be keywords and don't need to be prefixed with `r#` + +error: invalid format string: raw identifiers are not supported + --> $DIR/raw-idents.rs:10:14 + | +LL | println!(concat!("{r#", "type}")); + | ^^^^^^^^^^^^^^^^^^^^^^^ raw identifier used here in format string + | + = note: identifiers in format strings can be keywords and don't need to be prefixed with `r#` + = note: this error originates in the macro `concat` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: invalid format string: raw identifiers are not supported + --> $DIR/raw-idents.rs:11:16 + | +LL | println!("{\x72\x23type:?}"); + | --------^^^^ + | | + | raw identifier used here in format string + | help: remove the `r#` + | + = note: identifiers in format strings can be keywords and don't need to be prefixed with `r#` + +error: aborting due to 4 previous errors + diff --git a/tests/ui/generic-associated-types/bugs/issue-88460.stderr b/tests/ui/generic-associated-types/bugs/issue-88460.stderr index a2047f103d4..b9e2c4186c1 100644 --- a/tests/ui/generic-associated-types/bugs/issue-88460.stderr +++ b/tests/ui/generic-associated-types/bugs/issue-88460.stderr @@ -7,6 +7,14 @@ LL | test(Foo); | required by a bound introduced by this call | = help: the trait `Marker` is implemented for `()` +note: this is a known limitation of the trait solver that will be lifted in the future + --> $DIR/issue-88460.rs:28:10 + | +LL | test(Foo); + | -----^^^- + | | | + | | the trait solver is unable to infer the generic types that should be inferred from this argument + | add turbofish arguments to this call to specify the types manually, even if it's redundant note: required by a bound in `test` --> $DIR/issue-88460.rs:15:27 | diff --git a/tests/ui/generic-associated-types/issue-101020.stderr b/tests/ui/generic-associated-types/issue-101020.stderr index 5c8db617c17..91967fb8509 100644 --- a/tests/ui/generic-associated-types/issue-101020.stderr +++ b/tests/ui/generic-associated-types/issue-101020.stderr @@ -4,6 +4,11 @@ error[E0277]: the trait bound `for<'a> &'a mut (): Foo<&'a mut ()>` is not satis LL | (&mut EmptyIter).consume(()); | ^^^^^^^ the trait `for<'a> Foo<&'a mut ()>` is not implemented for `&'a mut ()` | +help: this trait has no implementations, consider adding one + --> $DIR/issue-101020.rs:28:1 + | +LL | trait Foo<T> {} + | ^^^^^^^^^^^^ note: required for `&'a mut ()` to implement `for<'a> FuncInput<'a, &'a mut ()>` --> $DIR/issue-101020.rs:27:20 | diff --git a/tests/ui/generics/issue-94432-garbage-ice.rs b/tests/ui/generics/issue-94432-garbage-ice.rs index d0709e2d2a4..4ddb3a7e9f8 100644 --- a/tests/ui/generics/issue-94432-garbage-ice.rs +++ b/tests/ui/generics/issue-94432-garbage-ice.rs @@ -4,7 +4,7 @@ fn�a<e>(){fn�p(){e}} //~ ERROR unknown start of token: \u{fffd} //~^ ERROR unknown start of token: \u{fffd} -//~^^ ERROR can't use generic parameters from outer function [E0401] +//~^^ ERROR can't use generic parameters from outer item [E0401] //~^^^ WARN type parameter `e` should have an upper camel case name fn main(){} diff --git a/tests/ui/generics/issue-98432.rs b/tests/ui/generics/issue-98432.rs index 780c50d6ffa..c31dea76c09 100644 --- a/tests/ui/generics/issue-98432.rs +++ b/tests/ui/generics/issue-98432.rs @@ -2,7 +2,7 @@ struct Struct<T>(T); impl<T> Struct<T> { const CONST: fn() = || { - struct _Obligation where T:; //~ ERROR can't use generic parameters from outer function + struct _Obligation where T:; //~ ERROR can't use generic parameters from outer item }; } diff --git a/tests/ui/generics/issue-98432.stderr b/tests/ui/generics/issue-98432.stderr index c7b5c33618d..0736d94106e 100644 --- a/tests/ui/generics/issue-98432.stderr +++ b/tests/ui/generics/issue-98432.stderr @@ -1,13 +1,13 @@ -error[E0401]: can't use generic parameters from outer function +error[E0401]: can't use generic parameters from outer item --> $DIR/issue-98432.rs:5:34 | LL | impl<T> Struct<T> { - | - type parameter from outer function + | - type parameter from outer item LL | const CONST: fn() = || { LL | struct _Obligation where T:; - | - ^ use of generic parameter from outer function + | - ^ use of generic parameter from outer item | | - | help: try using a local generic parameter instead: `<T>` + | help: try introducing a local generic parameter here: `<T>` error: aborting due to previous error diff --git a/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/issue-62529-3.stderr b/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/issue-62529-3.stderr index b30dd36d2ad..2cc2bb2bbc3 100644 --- a/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/issue-62529-3.stderr +++ b/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/issue-62529-3.stderr @@ -8,6 +8,14 @@ LL | call(f, ()); | = note: expected a closure with arguments `((),)` found a closure with arguments `(<_ as ATC<'a>>::Type,)` +note: this is a known limitation of the trait solver that will be lifted in the future + --> $DIR/issue-62529-3.rs:25:14 + | +LL | call(f, ()); + | -----^----- + | | | + | | the trait solver is unable to infer the generic types that should be inferred from this argument + | add turbofish arguments to this call to specify the types manually, even if it's redundant note: required by a bound in `call` --> $DIR/issue-62529-3.rs:9:36 | diff --git a/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/issue-89118.stderr b/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/issue-89118.stderr index edef6ccd34e..7fe803550bd 100644 --- a/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/issue-89118.stderr +++ b/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/issue-89118.stderr @@ -4,6 +4,11 @@ error[E0277]: the trait bound `for<'a> &'a (): BufferMut` is not satisfied LL | C: StackContext, | ^^^^^^^^^^^^ the trait `for<'a> BufferMut` is not implemented for `&'a ()` | +help: this trait has no implementations, consider adding one + --> $DIR/issue-89118.rs:1:1 + | +LL | trait BufferMut {} + | ^^^^^^^^^^^^^^^ note: required for `Ctx<()>` to implement `for<'a> BufferUdpStateContext<&'a ()>` --> $DIR/issue-89118.rs:5:23 | @@ -26,6 +31,11 @@ error[E0277]: the trait bound `for<'a> &'a (): BufferMut` is not satisfied LL | impl<C> EthernetWorker<C> {} | ^^^^^^^^^^^^^^^^^ the trait `for<'a> BufferMut` is not implemented for `&'a ()` | +help: this trait has no implementations, consider adding one + --> $DIR/issue-89118.rs:1:1 + | +LL | trait BufferMut {} + | ^^^^^^^^^^^^^^^ note: required for `Ctx<()>` to implement `for<'a> BufferUdpStateContext<&'a ()>` --> $DIR/issue-89118.rs:5:23 | @@ -48,6 +58,11 @@ error[E0277]: the trait bound `for<'a> &'a (): BufferMut` is not satisfied LL | type Handler = Ctx<C::Dispatcher>; | ^^^^^^^^^^^^^^^^^^ the trait `for<'a> BufferMut` is not implemented for `&'a ()` | +help: this trait has no implementations, consider adding one + --> $DIR/issue-89118.rs:1:1 + | +LL | trait BufferMut {} + | ^^^^^^^^^^^^^^^ note: required for `Ctx<()>` to implement `for<'a> BufferUdpStateContext<&'a ()>` --> $DIR/issue-89118.rs:5:23 | diff --git a/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/issue-90950.stderr b/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/issue-90950.stderr index 5be33bccdc3..55eaef78634 100644 --- a/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/issue-90950.stderr +++ b/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/issue-90950.stderr @@ -7,6 +7,14 @@ LL | upcast(y) | required by a bound introduced by this call | = help: the trait `IsCovariant<'a>` is implemented for `std::borrow::Cow<'a, T>` +note: this is a known limitation of the trait solver that will be lifted in the future + --> $DIR/issue-90950.rs:50:12 + | +LL | upcast(y) + | -------^- + | | | + | | the trait solver is unable to infer the generic types that should be inferred from this argument + | add turbofish arguments to this call to specify the types manually, even if it's redundant note: required by a bound in `upcast` --> $DIR/issue-90950.rs:27:42 | diff --git a/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/norm-before-method-resolution.stderr b/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/norm-before-method-resolution.stderr index 73388a72574..081dbb67df8 100644 --- a/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/norm-before-method-resolution.stderr +++ b/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/norm-before-method-resolution.stderr @@ -4,6 +4,11 @@ error[E0277]: the trait bound `for<'a> <_ as Trait<'a>>::Out: Copy` is not satis LL | let _: () = weird_bound(); | ^^^^^^^^^^^ the trait `for<'a> Copy` is not implemented for `<_ as Trait<'a>>::Out` | +note: this is a known limitation of the trait solver that will be lifted in the future + --> $DIR/norm-before-method-resolution.rs:22:17 + | +LL | let _: () = weird_bound(); + | ^^^^^^^^^^^ try adding turbofish arguments to this expression to specify the types manually, even if it's redundant note: required by a bound in `weird_bound` --> $DIR/norm-before-method-resolution.rs:18:40 | diff --git a/tests/ui/impl-trait/async_scope_creep.rs b/tests/ui/impl-trait/async_scope_creep.rs index 7a9d64d339f..9a8831a299e 100644 --- a/tests/ui/impl-trait/async_scope_creep.rs +++ b/tests/ui/impl-trait/async_scope_creep.rs @@ -1,6 +1,7 @@ #![feature(type_alias_impl_trait)] // edition:2021 -// check-pass +//[rpit] check-pass +// revisions: tait rpit struct Pending {} @@ -12,15 +13,23 @@ impl AsyncRead for i32 {} type PendingReader<'a> = impl AsyncRead + 'a; -type OpeningReadFuture<'a> = - impl std::future::Future<Output = Result<PendingReader<'a>, CantOpen>>; +#[cfg(tait)] +type OpeningReadFuture<'a> = impl std::future::Future<Output = Result<PendingReader<'a>, CantOpen>>; impl Pending { async fn read(&mut self) -> Result<impl AsyncRead + '_, CantOpen> { Ok(42) } + #[cfg(tait)] fn read_fut(&mut self) -> OpeningReadFuture<'_> { + self.read() //[tait]~ ERROR: cannot satisfy `impl AsyncRead + 'a == PendingReader<'a>` + } + + #[cfg(rpit)] + fn read_fut( + &mut self, + ) -> impl std::future::Future<Output = Result<PendingReader<'_>, CantOpen>> { self.read() } } diff --git a/tests/ui/impl-trait/async_scope_creep.tait.stderr b/tests/ui/impl-trait/async_scope_creep.tait.stderr new file mode 100644 index 00000000000..165096a0574 --- /dev/null +++ b/tests/ui/impl-trait/async_scope_creep.tait.stderr @@ -0,0 +1,9 @@ +error[E0284]: type annotations needed: cannot satisfy `impl AsyncRead + 'a == PendingReader<'a>` + --> $DIR/async_scope_creep.rs:26:9 + | +LL | self.read() + | ^^^^^^^^^^^ cannot satisfy `impl AsyncRead + 'a == PendingReader<'a>` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0284`. diff --git a/tests/ui/impl-trait/lifetime-ambiguity-regression.rs b/tests/ui/impl-trait/lifetime-ambiguity-regression.rs new file mode 100644 index 00000000000..ce6ae3786e1 --- /dev/null +++ b/tests/ui/impl-trait/lifetime-ambiguity-regression.rs @@ -0,0 +1,13 @@ +//! This test shows a situation where through subtle compiler changes we can +//! suddenly infer a different lifetime in the hidden type, and thus not meet +//! the opaque type bounds anymore. In this case `'a` and `'b` are equal, so +//! picking either is fine, but then we'll fail an identity check of the hidden +//! type and the expected hidden type. + +// check-pass + +fn test<'a: 'b, 'b: 'a>() -> impl IntoIterator<Item = (&'a u8, impl Into<(&'b u8, &'a u8)>)> { + None::<(_, (_, _))> +} + +fn main() {} diff --git a/tests/ui/imports/import-after-macro-expand-10.rs b/tests/ui/imports/import-after-macro-expand-10.rs new file mode 100644 index 00000000000..b3520c42dfc --- /dev/null +++ b/tests/ui/imports/import-after-macro-expand-10.rs @@ -0,0 +1,17 @@ +// check-pass + +mod b { + pub mod http { + pub struct HeaderMap; + } + + pub use self::http::*; + #[derive(Debug)] + pub struct HeaderMap; +} + +use crate::b::*; + +fn main() { + let h: crate::b::HeaderMap = HeaderMap; +} diff --git a/tests/ui/imports/import-after-macro-expand-11.rs b/tests/ui/imports/import-after-macro-expand-11.rs new file mode 100644 index 00000000000..2b81dfc236a --- /dev/null +++ b/tests/ui/imports/import-after-macro-expand-11.rs @@ -0,0 +1,21 @@ +// check-pass + +#[derive(Debug)] +struct H; + +mod p { + use super::*; + + #[derive(Clone)] + struct H; + + mod t { + use super::*; + + fn f() { + let h: crate::p::H = H; + } + } +} + +fn main() {} diff --git a/tests/ui/imports/import-after-macro-expand-12.rs b/tests/ui/imports/import-after-macro-expand-12.rs new file mode 100644 index 00000000000..f92e8c12fca --- /dev/null +++ b/tests/ui/imports/import-after-macro-expand-12.rs @@ -0,0 +1,34 @@ +// check-pass +// https://github.com/rust-lang/rust/issues/115377 + +use module::*; + +mod module { + pub enum B {} + impl B { + pub const ASSOC: u8 = 0; + } +} + +#[derive()] +pub enum B {} +impl B { + pub const ASSOC: u16 = 0; +} + +macro_rules! m { + ($right:expr) => { + $right + }; +} + +fn main() { + let a: u16 = { + use self::*; + B::ASSOC + }; + let b: u16 = m!({ + use self::*; + B::ASSOC + }); +} diff --git a/tests/ui/imports/import-after-macro-expand-13.rs b/tests/ui/imports/import-after-macro-expand-13.rs new file mode 100644 index 00000000000..fd640002c3e --- /dev/null +++ b/tests/ui/imports/import-after-macro-expand-13.rs @@ -0,0 +1,22 @@ +// check-pass +// similar as `import-after-macro-expand-6.rs` + +use crate::a::HeaderMap; + +mod b { + pub mod http { + pub struct HeaderMap; + } + + pub use self::http::*; + #[derive(Debug)] + pub struct HeaderMap; +} + +mod a { + pub use crate::b::*; +} + +fn main() { + let h: crate::b::HeaderMap = HeaderMap; +} diff --git a/tests/ui/imports/import-after-macro-expand-14.rs b/tests/ui/imports/import-after-macro-expand-14.rs new file mode 100644 index 00000000000..4d461a0e20c --- /dev/null +++ b/tests/ui/imports/import-after-macro-expand-14.rs @@ -0,0 +1,22 @@ +// check-pass + +use crate::a::HeaderMap; + +mod b { + pub mod http { + #[derive(Clone)] + pub struct HeaderMap; + } + + pub use self::http::*; + #[derive(Debug)] + pub struct HeaderMap; +} + +mod a { + pub use crate::b::*; +} + +fn main() { + let h: crate::b::HeaderMap = HeaderMap; +} diff --git a/tests/ui/imports/import-after-macro-expand-2.rs b/tests/ui/imports/import-after-macro-expand-2.rs index b3996d48840..ff773fc8272 100644 --- a/tests/ui/imports/import-after-macro-expand-2.rs +++ b/tests/ui/imports/import-after-macro-expand-2.rs @@ -12,9 +12,7 @@ mod tests { use super::*; fn test_thing() { - let thing: crate::thing::Thing = Thing::Bar; - // FIXME: `thing` should refer to `crate::Thing`, - // FIXME: but doesn't currently refer to it due to backward compatibility + let thing: crate::Thing = Thing::Foo; } } diff --git a/tests/ui/imports/import-after-macro-expand-4.rs b/tests/ui/imports/import-after-macro-expand-4.rs index 02cc3f01af9..fc0a232a93c 100644 --- a/tests/ui/imports/import-after-macro-expand-4.rs +++ b/tests/ui/imports/import-after-macro-expand-4.rs @@ -1,3 +1,4 @@ +// check-pass // https://github.com/rust-lang/rust/pull/113242#issuecomment-1616034904 // similar with `import-after-macro-expand-2.rs` @@ -10,16 +11,6 @@ pub use a::*; mod c { use crate::*; pub struct S(Vec<P>); - //~^ ERROR the size for values of type - //~| WARNING trait objects without an explicit - //~| WARNING this is accepted in the current edition - //~| WARNING trait objects without an explicit - //~| WARNING this is accepted in the current edition - //~| WARNING trait objects without an explicit - //~| WARNING this is accepted in the current edition - - // FIXME: should works, but doesn't currently refer - // to it due to backward compatibility } #[derive(Clone)] diff --git a/tests/ui/imports/import-after-macro-expand-4.stderr b/tests/ui/imports/import-after-macro-expand-4.stderr deleted file mode 100644 index 01f70cfc5bf..00000000000 --- a/tests/ui/imports/import-after-macro-expand-4.stderr +++ /dev/null @@ -1,53 +0,0 @@ -warning: trait objects without an explicit `dyn` are deprecated - --> $DIR/import-after-macro-expand-4.rs:12:22 - | -LL | pub struct S(Vec<P>); - | ^ - | - = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021! - = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html> - = note: `#[warn(bare_trait_objects)]` on by default -help: use `dyn` - | -LL | pub struct S(Vec<dyn P>); - | +++ - -warning: trait objects without an explicit `dyn` are deprecated - --> $DIR/import-after-macro-expand-4.rs:12:22 - | -LL | pub struct S(Vec<P>); - | ^ - | - = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021! - = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html> -help: use `dyn` - | -LL | pub struct S(Vec<dyn P>); - | +++ - -warning: trait objects without an explicit `dyn` are deprecated - --> $DIR/import-after-macro-expand-4.rs:12:22 - | -LL | pub struct S(Vec<P>); - | ^ - | - = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021! - = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html> -help: use `dyn` - | -LL | pub struct S(Vec<dyn P>); - | +++ - -error[E0277]: the size for values of type `(dyn a::P + 'static)` cannot be known at compilation time - --> $DIR/import-after-macro-expand-4.rs:12:18 - | -LL | pub struct S(Vec<P>); - | ^^^^^^ doesn't have a size known at compile-time - | - = help: the trait `Sized` is not implemented for `(dyn a::P + 'static)` -note: required by a bound in `Vec` - --> $SRC_DIR/alloc/src/vec/mod.rs:LL:COL - -error: aborting due to previous error; 3 warnings emitted - -For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/imports/import-after-macro-expand-6.rs b/tests/ui/imports/import-after-macro-expand-6.rs index ab5bb37a175..bff8efebca6 100644 --- a/tests/ui/imports/import-after-macro-expand-6.rs +++ b/tests/ui/imports/import-after-macro-expand-6.rs @@ -18,7 +18,5 @@ mod b { use crate::a::HeaderMap; fn main() { - let h: crate::b::http::HeaderMap = HeaderMap; - // FIXME: should refer to `crate::b::HeaderMap`, - // FIXME: but doesn't currently refer to it due to backward compatibility + let h: crate::b::HeaderMap = HeaderMap; } diff --git a/tests/ui/imports/import-after-macro-expand-9.rs b/tests/ui/imports/import-after-macro-expand-9.rs new file mode 100644 index 00000000000..deee42c3b84 --- /dev/null +++ b/tests/ui/imports/import-after-macro-expand-9.rs @@ -0,0 +1,17 @@ +// check-pass + +use crate::b::*; + +mod b { + pub mod http { + pub struct HeaderMap; + } + + pub use self::http::*; + #[derive(Debug)] + pub struct HeaderMap; +} + +fn main() { + let h: crate::b::HeaderMap = HeaderMap; +} diff --git a/tests/ui/inner-static-type-parameter.rs b/tests/ui/inner-static-type-parameter.rs index c08ccd29d80..a1994e7529c 100644 --- a/tests/ui/inner-static-type-parameter.rs +++ b/tests/ui/inner-static-type-parameter.rs @@ -4,7 +4,7 @@ enum Bar<T> { What } //~ ERROR parameter `T` is never used fn foo<T>() { static a: Bar<T> = Bar::What; -//~^ ERROR can't use generic parameters from outer function +//~^ ERROR can't use generic parameters from outer item } fn main() { diff --git a/tests/ui/inner-static-type-parameter.stderr b/tests/ui/inner-static-type-parameter.stderr index e4e449e4159..ff6558e494b 100644 --- a/tests/ui/inner-static-type-parameter.stderr +++ b/tests/ui/inner-static-type-parameter.stderr @@ -1,10 +1,10 @@ -error[E0401]: can't use generic parameters from outer function +error[E0401]: can't use generic parameters from outer item --> $DIR/inner-static-type-parameter.rs:6:19 | LL | fn foo<T>() { - | - type parameter from outer function + | - type parameter from outer item LL | static a: Bar<T> = Bar::What; - | ^ use of generic parameter from outer function + | ^ use of generic parameter from outer item error[E0392]: parameter `T` is never used --> $DIR/inner-static-type-parameter.rs:3:10 diff --git a/tests/ui/issues/issue-17252.stderr b/tests/ui/issues/issue-17252.stderr index daaf82e80ad..32e20d77465 100644 --- a/tests/ui/issues/issue-17252.stderr +++ b/tests/ui/issues/issue-17252.stderr @@ -1,10 +1,15 @@ -error[E0391]: cycle detected when const-evaluating + checking `FOO` +error[E0391]: cycle detected when simplifying constant for the type system `FOO` + --> $DIR/issue-17252.rs:1:1 + | +LL | const FOO: usize = FOO; + | ^^^^^^^^^^^^^^^^ + | +note: ...which requires const-evaluating + checking `FOO`... --> $DIR/issue-17252.rs:1:20 | LL | const FOO: usize = FOO; | ^^^ - | - = note: ...which immediately requires const-evaluating + checking `FOO` again + = note: ...which again requires simplifying constant for the type system `FOO`, completing the cycle note: cycle used when const-evaluating + checking `main::{constant#0}` --> $DIR/issue-17252.rs:4:18 | diff --git a/tests/ui/issues/issue-18611.stderr b/tests/ui/issues/issue-18611.stderr index bd18d46223e..784b9b984e9 100644 --- a/tests/ui/issues/issue-18611.stderr +++ b/tests/ui/issues/issue-18611.stderr @@ -3,6 +3,12 @@ error[E0277]: the trait bound `isize: HasState` is not satisfied | LL | fn add_state(op: <isize as HasState>::State) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `HasState` is not implemented for `isize` + | +help: this trait has no implementations, consider adding one + --> $DIR/issue-18611.rs:5:1 + | +LL | trait HasState { + | ^^^^^^^^^^^^^^ error: aborting due to previous error diff --git a/tests/ui/issues/issue-21763.stderr b/tests/ui/issues/issue-21763.stderr index df50118ac47..a887635d354 100644 --- a/tests/ui/issues/issue-21763.stderr +++ b/tests/ui/issues/issue-21763.stderr @@ -9,9 +9,6 @@ LL | foo::<HashMap<Rc<()>, Rc<()>>>(); = note: required for `hashbrown::raw::RawTable<(Rc<()>, Rc<()>)>` to implement `Send` note: required because it appears within the type `HashMap<Rc<()>, Rc<()>, RandomState>` --> $HASHBROWN_SRC_LOCATION - | -LL | pub struct HashMap<K, V, S = DefaultHashBuilder, A: Allocator + Clone = Global> { - | ^^^^^^^ note: required because it appears within the type `HashMap<Rc<()>, Rc<()>>` --> $SRC_DIR/std/src/collections/hash/map.rs:LL:COL note: required by a bound in `foo` diff --git a/tests/ui/issues/issue-23302-1.stderr b/tests/ui/issues/issue-23302-1.stderr index d807e24403e..d753bdeb9f7 100644 --- a/tests/ui/issues/issue-23302-1.stderr +++ b/tests/ui/issues/issue-23302-1.stderr @@ -1,10 +1,15 @@ -error[E0391]: cycle detected when const-evaluating + checking `X::A::{constant#0}` +error[E0391]: cycle detected when simplifying constant for the type system `X::A::{constant#0}` --> $DIR/issue-23302-1.rs:4:9 | LL | A = X::A as isize, | ^^^^^^^^^^^^^ | - = note: ...which immediately requires const-evaluating + checking `X::A::{constant#0}` again +note: ...which requires const-evaluating + checking `X::A::{constant#0}`... + --> $DIR/issue-23302-1.rs:4:9 + | +LL | A = X::A as isize, + | ^^^^^^^^^^^^^ + = note: ...which again requires simplifying constant for the type system `X::A::{constant#0}`, completing the cycle note: cycle used when simplifying constant for the type system `X::A::{constant#0}` --> $DIR/issue-23302-1.rs:4:9 | diff --git a/tests/ui/issues/issue-23302-2.stderr b/tests/ui/issues/issue-23302-2.stderr index 91b39dba1ba..b756ee1d5e2 100644 --- a/tests/ui/issues/issue-23302-2.stderr +++ b/tests/ui/issues/issue-23302-2.stderr @@ -1,10 +1,15 @@ -error[E0391]: cycle detected when const-evaluating + checking `Y::A::{constant#0}` +error[E0391]: cycle detected when simplifying constant for the type system `Y::A::{constant#0}` --> $DIR/issue-23302-2.rs:4:9 | LL | A = Y::B as isize, | ^^^^^^^^^^^^^ | - = note: ...which immediately requires const-evaluating + checking `Y::A::{constant#0}` again +note: ...which requires const-evaluating + checking `Y::A::{constant#0}`... + --> $DIR/issue-23302-2.rs:4:9 + | +LL | A = Y::B as isize, + | ^^^^^^^^^^^^^ + = note: ...which again requires simplifying constant for the type system `Y::A::{constant#0}`, completing the cycle note: cycle used when simplifying constant for the type system `Y::A::{constant#0}` --> $DIR/issue-23302-2.rs:4:9 | diff --git a/tests/ui/issues/issue-23302-3.stderr b/tests/ui/issues/issue-23302-3.stderr index 6b708d81f73..6cdc94551fe 100644 --- a/tests/ui/issues/issue-23302-3.stderr +++ b/tests/ui/issues/issue-23302-3.stderr @@ -1,15 +1,25 @@ -error[E0391]: cycle detected when const-evaluating + checking `A` +error[E0391]: cycle detected when simplifying constant for the type system `A` + --> $DIR/issue-23302-3.rs:1:1 + | +LL | const A: i32 = B; + | ^^^^^^^^^^^^ + | +note: ...which requires const-evaluating + checking `A`... --> $DIR/issue-23302-3.rs:1:16 | LL | const A: i32 = B; | ^ +note: ...which requires simplifying constant for the type system `B`... + --> $DIR/issue-23302-3.rs:3:1 | +LL | const B: i32 = A; + | ^^^^^^^^^^^^ note: ...which requires const-evaluating + checking `B`... --> $DIR/issue-23302-3.rs:3:16 | LL | const B: i32 = A; | ^ - = note: ...which again requires const-evaluating + checking `A`, completing the cycle + = note: ...which again requires simplifying constant for the type system `A`, completing the cycle note: cycle used when simplifying constant for the type system `A` --> $DIR/issue-23302-3.rs:1:1 | diff --git a/tests/ui/issues/issue-25076.stderr b/tests/ui/issues/issue-25076.stderr index 159cc484c5d..065bf7def42 100644 --- a/tests/ui/issues/issue-25076.stderr +++ b/tests/ui/issues/issue-25076.stderr @@ -6,6 +6,11 @@ LL | do_fold(bot(), ()); | | | required by a bound introduced by this call | +help: this trait has no implementations, consider adding one + --> $DIR/issue-25076.rs:3:1 + | +LL | trait InOut<T> { type Out; } + | ^^^^^^^^^^^^^^ note: required by a bound in `do_fold` --> $DIR/issue-25076.rs:5:18 | diff --git a/tests/ui/issues/issue-3214.rs b/tests/ui/issues/issue-3214.rs index e3c07bb3f72..b2c27f5be95 100644 --- a/tests/ui/issues/issue-3214.rs +++ b/tests/ui/issues/issue-3214.rs @@ -1,6 +1,6 @@ fn foo<T>() { struct Foo { - x: T, //~ ERROR can't use generic parameters from outer function + x: T, //~ ERROR can't use generic parameters from outer item } impl<T> Drop for Foo<T> { diff --git a/tests/ui/issues/issue-3214.stderr b/tests/ui/issues/issue-3214.stderr index 7a2d772f0a1..5b57c1baf90 100644 --- a/tests/ui/issues/issue-3214.stderr +++ b/tests/ui/issues/issue-3214.stderr @@ -1,12 +1,12 @@ -error[E0401]: can't use generic parameters from outer function +error[E0401]: can't use generic parameters from outer item --> $DIR/issue-3214.rs:3:12 | LL | fn foo<T>() { - | - type parameter from outer function + | - type parameter from outer item LL | struct Foo { - | - help: try using a local generic parameter instead: `<T>` + | - help: try introducing a local generic parameter here: `<T>` LL | x: T, - | ^ use of generic parameter from outer function + | ^ use of generic parameter from outer item error[E0107]: struct takes 0 generic arguments but 1 generic argument was supplied --> $DIR/issue-3214.rs:6:22 diff --git a/tests/ui/issues/issue-35570.stderr b/tests/ui/issues/issue-35570.stderr index 2697d46bdb2..197e80ac097 100644 --- a/tests/ui/issues/issue-35570.stderr +++ b/tests/ui/issues/issue-35570.stderr @@ -3,6 +3,12 @@ error[E0277]: the trait bound `for<'a> (): Trait2<'a>` is not satisfied | LL | fn _ice(param: Box<dyn for <'a> Trait1<<() as Trait2<'a>>::Ty>>) { | ^^^^^^^^^^^^^^^^^^^^^^ the trait `for<'a> Trait2<'a>` is not implemented for `()` + | +help: this trait has no implementations, consider adding one + --> $DIR/issue-35570.rs:4:1 + | +LL | trait Trait2<'a> { + | ^^^^^^^^^^^^^^^^ error: aborting due to previous error diff --git a/tests/ui/issues/issue-5997-enum.rs b/tests/ui/issues/issue-5997-enum.rs index 3ff4e036c60..0b1857ae3df 100644 --- a/tests/ui/issues/issue-5997-enum.rs +++ b/tests/ui/issues/issue-5997-enum.rs @@ -1,6 +1,6 @@ fn f<Z>() -> bool { enum E { V(Z) } - //~^ ERROR can't use generic parameters from outer function + //~^ ERROR can't use generic parameters from outer item true } diff --git a/tests/ui/issues/issue-5997-enum.stderr b/tests/ui/issues/issue-5997-enum.stderr index 3a79215d3ae..d07258ea7a2 100644 --- a/tests/ui/issues/issue-5997-enum.stderr +++ b/tests/ui/issues/issue-5997-enum.stderr @@ -1,12 +1,12 @@ -error[E0401]: can't use generic parameters from outer function +error[E0401]: can't use generic parameters from outer item --> $DIR/issue-5997-enum.rs:2:16 | LL | fn f<Z>() -> bool { - | - type parameter from outer function + | - type parameter from outer item LL | enum E { V(Z) } - | - ^ use of generic parameter from outer function + | - ^ use of generic parameter from outer item | | - | help: try using a local generic parameter instead: `<Z>` + | help: try introducing a local generic parameter here: `<Z>` error: aborting due to previous error diff --git a/tests/ui/issues/issue-5997-struct.rs b/tests/ui/issues/issue-5997-struct.rs index 6cf510b0a9d..19d994b0dfb 100644 --- a/tests/ui/issues/issue-5997-struct.rs +++ b/tests/ui/issues/issue-5997-struct.rs @@ -1,5 +1,5 @@ fn f<T>() -> bool { - struct S(T); //~ ERROR can't use generic parameters from outer function + struct S(T); //~ ERROR can't use generic parameters from outer item true } diff --git a/tests/ui/issues/issue-5997-struct.stderr b/tests/ui/issues/issue-5997-struct.stderr index d2e97f76771..83229e02c6c 100644 --- a/tests/ui/issues/issue-5997-struct.stderr +++ b/tests/ui/issues/issue-5997-struct.stderr @@ -1,12 +1,12 @@ -error[E0401]: can't use generic parameters from outer function +error[E0401]: can't use generic parameters from outer item --> $DIR/issue-5997-struct.rs:2:14 | LL | fn f<T>() -> bool { - | - type parameter from outer function + | - type parameter from outer item LL | struct S(T); - | -^ use of generic parameter from outer function + | -^ use of generic parameter from outer item | | - | help: try using a local generic parameter instead: `<T>` + | help: try introducing a local generic parameter here: `<T>` error: aborting due to previous error diff --git a/tests/ui/issues/issue-60218.stderr b/tests/ui/issues/issue-60218.stderr index 563690c9a5d..ae3c4d12025 100644 --- a/tests/ui/issues/issue-60218.stderr +++ b/tests/ui/issues/issue-60218.stderr @@ -6,6 +6,11 @@ LL | trigger_error(vec![], |x: &u32| x) | | | required by a bound introduced by this call | +help: this trait has no implementations, consider adding one + --> $DIR/issue-60218.rs:7:1 + | +LL | pub trait Foo {} + | ^^^^^^^^^^^^^ note: required by a bound in `trigger_error` --> $DIR/issue-60218.rs:13:72 | diff --git a/tests/ui/issues/issue-66353.stderr b/tests/ui/issues/issue-66353.stderr index 71530f58220..7ab7547b42d 100644 --- a/tests/ui/issues/issue-66353.stderr +++ b/tests/ui/issues/issue-66353.stderr @@ -3,6 +3,12 @@ error[E0277]: the trait bound `(): _A` is not satisfied | LL | _Func::< <() as _A>::AssocT >::func(()); | ^^ the trait `_A` is not implemented for `()` + | +help: this trait has no implementations, consider adding one + --> $DIR/issue-66353.rs:7:1 + | +LL | trait _A { + | ^^^^^^^^ error[E0277]: the trait bound `(): _Func<_>` is not satisfied --> $DIR/issue-66353.rs:12:41 @@ -11,6 +17,12 @@ LL | _Func::< <() as _A>::AssocT >::func(()); | ----------------------------------- ^^ the trait `_Func<_>` is not implemented for `()` | | | required by a bound introduced by this call + | +help: this trait has no implementations, consider adding one + --> $DIR/issue-66353.rs:3:1 + | +LL | trait _Func<T> { + | ^^^^^^^^^^^^^^ error: aborting due to 2 previous errors diff --git a/tests/ui/issues/issue-69602-type-err-during-codegen-ice.stderr b/tests/ui/issues/issue-69602-type-err-during-codegen-ice.stderr index ba385d887fb..6f9302bc4a5 100644 --- a/tests/ui/issues/issue-69602-type-err-during-codegen-ice.stderr +++ b/tests/ui/issues/issue-69602-type-err-during-codegen-ice.stderr @@ -13,7 +13,7 @@ LL | type MyA: TraitA; LL | impl TraitB for B { | ^^^^^^^^^^^^^^^^^ missing `MyA` in implementation -note: erroneous constant used +note: erroneous constant encountered --> $DIR/issue-69602-type-err-during-codegen-ice.rs:21:17 | LL | let _ = [0; B::VALUE]; diff --git a/tests/ui/layout/homogeneous-aggr-transparent.rs b/tests/ui/layout/homogeneous-aggr-transparent.rs new file mode 100644 index 00000000000..9703d2bf294 --- /dev/null +++ b/tests/ui/layout/homogeneous-aggr-transparent.rs @@ -0,0 +1,44 @@ +#![feature(rustc_attrs)] +#![feature(transparent_unions)] +use std::marker::PhantomData; + +// Regression test for #115664. We want to ensure that `repr(transparent)` wrappers do not affect +// the result of `homogeneous_aggregate`. + +type Tuple = (f32, f32, f32); + +struct Zst; + +#[repr(transparent)] +struct Wrapper1<T>(T); +#[repr(transparent)] +struct Wrapper2<T>((), Zst, T); +#[repr(transparent)] +struct Wrapper3<T>(T, [u8; 0], PhantomData<u64>); +#[repr(transparent)] +union WrapperUnion<T: Copy> { + nothing: (), + something: T, +} + +#[rustc_layout(homogeneous_aggregate)] +pub type Test0 = Tuple; +//~^ ERROR homogeneous_aggregate: Ok(Homogeneous(Reg { kind: Float, size: Size(4 bytes) })) + +#[rustc_layout(homogeneous_aggregate)] +pub type Test1 = Wrapper1<Tuple>; +//~^ ERROR homogeneous_aggregate: Ok(Homogeneous(Reg { kind: Float, size: Size(4 bytes) })) + +#[rustc_layout(homogeneous_aggregate)] +pub type Test2 = Wrapper2<Tuple>; +//~^ ERROR homogeneous_aggregate: Ok(Homogeneous(Reg { kind: Float, size: Size(4 bytes) })) + +#[rustc_layout(homogeneous_aggregate)] +pub type Test3 = Wrapper3<Tuple>; +//~^ ERROR homogeneous_aggregate: Ok(Homogeneous(Reg { kind: Float, size: Size(4 bytes) })) + +#[rustc_layout(homogeneous_aggregate)] +pub type Test4 = WrapperUnion<Tuple>; +//~^ ERROR homogeneous_aggregate: Ok(Homogeneous(Reg { kind: Float, size: Size(4 bytes) })) + +fn main() {} diff --git a/tests/ui/layout/homogeneous-aggr-transparent.stderr b/tests/ui/layout/homogeneous-aggr-transparent.stderr new file mode 100644 index 00000000000..99eb703ac82 --- /dev/null +++ b/tests/ui/layout/homogeneous-aggr-transparent.stderr @@ -0,0 +1,32 @@ +error: homogeneous_aggregate: Ok(Homogeneous(Reg { kind: Float, size: Size(4 bytes) })) + --> $DIR/homogeneous-aggr-transparent.rs:25:1 + | +LL | pub type Test0 = Tuple; + | ^^^^^^^^^^^^^^ + +error: homogeneous_aggregate: Ok(Homogeneous(Reg { kind: Float, size: Size(4 bytes) })) + --> $DIR/homogeneous-aggr-transparent.rs:29:1 + | +LL | pub type Test1 = Wrapper1<Tuple>; + | ^^^^^^^^^^^^^^ + +error: homogeneous_aggregate: Ok(Homogeneous(Reg { kind: Float, size: Size(4 bytes) })) + --> $DIR/homogeneous-aggr-transparent.rs:33:1 + | +LL | pub type Test2 = Wrapper2<Tuple>; + | ^^^^^^^^^^^^^^ + +error: homogeneous_aggregate: Ok(Homogeneous(Reg { kind: Float, size: Size(4 bytes) })) + --> $DIR/homogeneous-aggr-transparent.rs:37:1 + | +LL | pub type Test3 = Wrapper3<Tuple>; + | ^^^^^^^^^^^^^^ + +error: homogeneous_aggregate: Ok(Homogeneous(Reg { kind: Float, size: Size(4 bytes) })) + --> $DIR/homogeneous-aggr-transparent.rs:41:1 + | +LL | pub type Test4 = WrapperUnion<Tuple>; + | ^^^^^^^^^^^^^^ + +error: aborting due to 5 previous errors + diff --git a/tests/ui/lifetimes/anonymize-unnamed-bound-vars-in-binders.rs b/tests/ui/lifetimes/anonymize-unnamed-bound-vars-in-binders.rs new file mode 100644 index 00000000000..05e3763e9d1 --- /dev/null +++ b/tests/ui/lifetimes/anonymize-unnamed-bound-vars-in-binders.rs @@ -0,0 +1,27 @@ +// build-pass +// issue: #115807 + +trait Chip: for<'a> TraitWithLifetime<'a> + SomeMarker { + fn compute(&self); +} + +trait SomeMarker {} + +trait TraitWithLifetime<'a>: SomeMarker {} + +trait Machine { + fn run(); +} + +struct BasicMachine; + +impl Machine for BasicMachine { + fn run() { + let chips: [&dyn Chip; 0] = []; + let _ = chips.map(|chip| chip.compute()); + } +} + +fn main() { + BasicMachine::run(); +} diff --git a/tests/ui/lifetimes/lifetime-elision-return-type-trait.stderr b/tests/ui/lifetimes/lifetime-elision-return-type-trait.stderr index ef1127c59ac..421ab3fcf4e 100644 --- a/tests/ui/lifetimes/lifetime-elision-return-type-trait.stderr +++ b/tests/ui/lifetimes/lifetime-elision-return-type-trait.stderr @@ -3,6 +3,12 @@ error[E0277]: the trait bound `Result<(), _>: Future` is not satisfied | LL | fn foo() -> impl Future<Item=(), Error=Box<dyn Error>> { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Future` is not implemented for `Result<(), _>` + | +help: this trait has no implementations, consider adding one + --> $DIR/lifetime-elision-return-type-trait.rs:1:1 + | +LL | trait Future { + | ^^^^^^^^^^^^ error: aborting due to previous error diff --git a/tests/ui/limits/issue-55878.stderr b/tests/ui/limits/issue-55878.stderr index 510b36edd8f..93716c0b347 100644 --- a/tests/ui/limits/issue-55878.stderr +++ b/tests/ui/limits/issue-55878.stderr @@ -1,6 +1,8 @@ -error[E0080]: values of the type `[u8; usize::MAX]` are too big for the current architecture +error[E0080]: evaluation of constant value failed --> $SRC_DIR/core/src/mem/mod.rs:LL:COL | + = note: values of the type `[u8; usize::MAX]` are too big for the current architecture + | note: inside `std::mem::size_of::<[u8; usize::MAX]>` --> $SRC_DIR/core/src/mem/mod.rs:LL:COL note: inside `main` @@ -9,7 +11,7 @@ note: inside `main` LL | println!("Size: {}", std::mem::size_of::<[u8; u64::MAX as usize]>()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -note: erroneous constant used +note: erroneous constant encountered --> $DIR/issue-55878.rs:7:26 | LL | println!("Size: {}", std::mem::size_of::<[u8; u64::MAX as usize]>()); @@ -17,7 +19,7 @@ LL | println!("Size: {}", std::mem::size_of::<[u8; u64::MAX as usize]>()); | = note: this note originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info) -note: erroneous constant used +note: erroneous constant encountered --> $DIR/issue-55878.rs:7:26 | LL | println!("Size: {}", std::mem::size_of::<[u8; u64::MAX as usize]>()); diff --git a/tests/ui/limits/issue-56762.rs b/tests/ui/limits/issue-56762.rs index ed7ee4da85d..1c7facb045d 100644 --- a/tests/ui/limits/issue-56762.rs +++ b/tests/ui/limits/issue-56762.rs @@ -14,8 +14,10 @@ impl TooBigArray { } static MY_TOO_BIG_ARRAY_1: TooBigArray = TooBigArray::new(); -//~^ ERROR values of the type `[u8; 2305843009213693951]` are too big +//~^ ERROR could not evaluate static initializer +//~| too big static MY_TOO_BIG_ARRAY_2: [u8; HUGE_SIZE] = [0x00; HUGE_SIZE]; -//~^ ERROR values of the type `[u8; 2305843009213693951]` are too big +//~^ ERROR could not evaluate static initializer +//~| too big fn main() { } diff --git a/tests/ui/limits/issue-56762.stderr b/tests/ui/limits/issue-56762.stderr index 29f2a8859ee..3a6c3559ac1 100644 --- a/tests/ui/limits/issue-56762.stderr +++ b/tests/ui/limits/issue-56762.stderr @@ -1,14 +1,14 @@ -error[E0080]: values of the type `[u8; 2305843009213693951]` are too big for the current architecture +error[E0080]: could not evaluate static initializer --> $DIR/issue-56762.rs:16:1 | LL | static MY_TOO_BIG_ARRAY_1: TooBigArray = TooBigArray::new(); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ values of the type `[u8; 2305843009213693951]` are too big for the current architecture -error[E0080]: values of the type `[u8; 2305843009213693951]` are too big for the current architecture - --> $DIR/issue-56762.rs:18:1 +error[E0080]: could not evaluate static initializer + --> $DIR/issue-56762.rs:19:1 | LL | static MY_TOO_BIG_ARRAY_2: [u8; HUGE_SIZE] = [0x00; HUGE_SIZE]; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ values of the type `[u8; 2305843009213693951]` are too big for the current architecture error: aborting due to 2 previous errors diff --git a/tests/ui/lint/expr-field.rs b/tests/ui/lint/expr-field.rs new file mode 100644 index 00000000000..638fbf521c4 --- /dev/null +++ b/tests/ui/lint/expr-field.rs @@ -0,0 +1,15 @@ +// check-pass + +pub struct A { + pub x: u32, +} + +#[deny(unused_comparisons)] +pub fn foo(y: u32) -> A { + A { + #[allow(unused_comparisons)] + x: if y < 0 { 1 } else { 2 }, + } +} + +fn main() {} diff --git a/tests/ui/lint/lint-ctypes-option-nonnull-unsized.rs b/tests/ui/lint/lint-ctypes-option-nonnull-unsized.rs new file mode 100644 index 00000000000..ca08eb23a57 --- /dev/null +++ b/tests/ui/lint/lint-ctypes-option-nonnull-unsized.rs @@ -0,0 +1,8 @@ +#![deny(improper_ctypes_definitions)] + +extern "C" fn foo<T: ?Sized + 'static>() -> Option<&'static T> { + //~^ ERROR `extern` fn uses type `Option<&T>`, which is not FFI-safe + None +} + +fn main() {} diff --git a/tests/ui/lint/lint-ctypes-option-nonnull-unsized.stderr b/tests/ui/lint/lint-ctypes-option-nonnull-unsized.stderr new file mode 100644 index 00000000000..f59fb3cc750 --- /dev/null +++ b/tests/ui/lint/lint-ctypes-option-nonnull-unsized.stderr @@ -0,0 +1,16 @@ +error: `extern` fn uses type `Option<&T>`, which is not FFI-safe + --> $DIR/lint-ctypes-option-nonnull-unsized.rs:3:45 + | +LL | extern "C" fn foo<T: ?Sized + 'static>() -> Option<&'static T> { + | ^^^^^^^^^^^^^^^^^^ not FFI-safe + | + = help: consider adding a `#[repr(C)]`, `#[repr(transparent)]`, or integer `#[repr(...)]` attribute to this enum + = note: enum has no representation hint +note: the lint level is defined here + --> $DIR/lint-ctypes-option-nonnull-unsized.rs:1:9 + | +LL | #![deny(improper_ctypes_definitions)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to previous error + diff --git a/tests/ui/lint/no-coverage.rs b/tests/ui/lint/no-coverage.rs index 07906a43472..907d25d333e 100644 --- a/tests/ui/lint/no-coverage.rs +++ b/tests/ui/lint/no-coverage.rs @@ -1,55 +1,55 @@ #![feature(extern_types)] -#![feature(no_coverage)] +#![feature(coverage_attribute)] #![feature(impl_trait_in_assoc_type)] #![warn(unused_attributes)] -#![no_coverage] -//~^ WARN: `#[no_coverage]` does not propagate into items and must be applied to the contained functions directly +#![coverage(off)] +//~^ WARN: `#[coverage]` does not propagate into items and must be applied to the contained functions directly -#[no_coverage] -//~^ WARN: `#[no_coverage]` does not propagate into items and must be applied to the contained functions directly +#[coverage(off)] +//~^ WARN: `#[coverage]` does not propagate into items and must be applied to the contained functions directly trait Trait { - #[no_coverage] //~ ERROR `#[no_coverage]` must be applied to coverable code + #[coverage(off)] //~ ERROR `#[coverage]` must be applied to coverable code const X: u32; - #[no_coverage] //~ ERROR `#[no_coverage]` must be applied to coverable code + #[coverage(off)] //~ ERROR `#[coverage]` must be applied to coverable code type T; type U; } -#[no_coverage] -//~^ WARN: `#[no_coverage]` does not propagate into items and must be applied to the contained functions directly +#[coverage(off)] +//~^ WARN: `#[coverage]` does not propagate into items and must be applied to the contained functions directly impl Trait for () { const X: u32 = 0; - #[no_coverage] //~ ERROR `#[no_coverage]` must be applied to coverable code + #[coverage(off)] //~ ERROR `#[coverage]` must be applied to coverable code type T = Self; - #[no_coverage] //~ ERROR `#[no_coverage]` must be applied to coverable code + #[coverage(off)] //~ ERROR `#[coverage]` must be applied to coverable code type U = impl Trait; //~ ERROR unconstrained opaque type } extern "C" { - #[no_coverage] //~ ERROR `#[no_coverage]` must be applied to coverable code + #[coverage(off)] //~ ERROR `#[coverage]` must be applied to coverable code static X: u32; - #[no_coverage] //~ ERROR `#[no_coverage]` must be applied to coverable code + #[coverage(off)] //~ ERROR `#[coverage]` must be applied to coverable code type T; } -#[no_coverage] +#[coverage(off)] fn main() { - #[no_coverage] - //~^ WARN `#[no_coverage]` may only be applied to function definitions + #[coverage(off)] + //~^ WARN `#[coverage]` may only be applied to function definitions let _ = (); match () { - #[no_coverage] - //~^ WARN `#[no_coverage]` may only be applied to function definitions + #[coverage(off)] + //~^ WARN `#[coverage]` may only be applied to function definitions () => (), } - #[no_coverage] - //~^ WARN `#[no_coverage]` may only be applied to function definitions + #[coverage(off)] + //~^ WARN `#[coverage]` may only be applied to function definitions return (); } diff --git a/tests/ui/lint/no-coverage.stderr b/tests/ui/lint/no-coverage.stderr index 404efbeac1e..a87b0fb49f0 100644 --- a/tests/ui/lint/no-coverage.stderr +++ b/tests/ui/lint/no-coverage.stderr @@ -1,8 +1,8 @@ -warning: `#[no_coverage]` does not propagate into items and must be applied to the contained functions directly +warning: `#[coverage]` does not propagate into items and must be applied to the contained functions directly --> $DIR/no-coverage.rs:8:1 | -LL | #[no_coverage] - | ^^^^^^^^^^^^^^ +LL | #[coverage(off)] + | ^^^^^^^^^^^^^^^^ | note: the lint level is defined here --> $DIR/no-coverage.rs:4:9 @@ -10,83 +10,83 @@ note: the lint level is defined here LL | #![warn(unused_attributes)] | ^^^^^^^^^^^^^^^^^ -warning: `#[no_coverage]` does not propagate into items and must be applied to the contained functions directly +warning: `#[coverage]` does not propagate into items and must be applied to the contained functions directly --> $DIR/no-coverage.rs:20:1 | -LL | #[no_coverage] - | ^^^^^^^^^^^^^^ +LL | #[coverage(off)] + | ^^^^^^^^^^^^^^^^ -warning: `#[no_coverage]` may only be applied to function definitions +warning: `#[coverage]` may only be applied to function definitions --> $DIR/no-coverage.rs:42:5 | -LL | #[no_coverage] - | ^^^^^^^^^^^^^^ +LL | #[coverage(off)] + | ^^^^^^^^^^^^^^^^ -warning: `#[no_coverage]` may only be applied to function definitions +warning: `#[coverage]` may only be applied to function definitions --> $DIR/no-coverage.rs:47:9 | -LL | #[no_coverage] - | ^^^^^^^^^^^^^^ +LL | #[coverage(off)] + | ^^^^^^^^^^^^^^^^ -warning: `#[no_coverage]` may only be applied to function definitions +warning: `#[coverage]` may only be applied to function definitions --> $DIR/no-coverage.rs:52:5 | -LL | #[no_coverage] - | ^^^^^^^^^^^^^^ +LL | #[coverage(off)] + | ^^^^^^^^^^^^^^^^ -error[E0788]: `#[no_coverage]` must be applied to coverable code +error[E0788]: `#[coverage]` must be applied to coverable code --> $DIR/no-coverage.rs:11:5 | -LL | #[no_coverage] - | ^^^^^^^^^^^^^^ +LL | #[coverage(off)] + | ^^^^^^^^^^^^^^^^ LL | const X: u32; | ------------- not coverable code -error[E0788]: `#[no_coverage]` must be applied to coverable code +error[E0788]: `#[coverage]` must be applied to coverable code --> $DIR/no-coverage.rs:14:5 | -LL | #[no_coverage] - | ^^^^^^^^^^^^^^ +LL | #[coverage(off)] + | ^^^^^^^^^^^^^^^^ LL | type T; | ------- not coverable code -error[E0788]: `#[no_coverage]` must be applied to coverable code +error[E0788]: `#[coverage]` must be applied to coverable code --> $DIR/no-coverage.rs:25:5 | -LL | #[no_coverage] - | ^^^^^^^^^^^^^^ +LL | #[coverage(off)] + | ^^^^^^^^^^^^^^^^ LL | type T = Self; | -------------- not coverable code -error[E0788]: `#[no_coverage]` must be applied to coverable code +error[E0788]: `#[coverage]` must be applied to coverable code --> $DIR/no-coverage.rs:28:5 | -LL | #[no_coverage] - | ^^^^^^^^^^^^^^ +LL | #[coverage(off)] + | ^^^^^^^^^^^^^^^^ LL | type U = impl Trait; | -------------------- not coverable code -error[E0788]: `#[no_coverage]` must be applied to coverable code +error[E0788]: `#[coverage]` must be applied to coverable code --> $DIR/no-coverage.rs:33:5 | -LL | #[no_coverage] - | ^^^^^^^^^^^^^^ +LL | #[coverage(off)] + | ^^^^^^^^^^^^^^^^ LL | static X: u32; | -------------- not coverable code -error[E0788]: `#[no_coverage]` must be applied to coverable code +error[E0788]: `#[coverage]` must be applied to coverable code --> $DIR/no-coverage.rs:36:5 | -LL | #[no_coverage] - | ^^^^^^^^^^^^^^ +LL | #[coverage(off)] + | ^^^^^^^^^^^^^^^^ LL | type T; | ------- not coverable code -warning: `#[no_coverage]` does not propagate into items and must be applied to the contained functions directly +warning: `#[coverage]` does not propagate into items and must be applied to the contained functions directly --> $DIR/no-coverage.rs:5:1 | -LL | #![no_coverage] - | ^^^^^^^^^^^^^^^ +LL | #![coverage(off)] + | ^^^^^^^^^^^^^^^^^ error: unconstrained opaque type --> $DIR/no-coverage.rs:29:14 diff --git a/tests/ui/lint/ptr_null_checks.rs b/tests/ui/lint/ptr_null_checks.rs index e677ea3094d..3028084e962 100644 --- a/tests/ui/lint/ptr_null_checks.rs +++ b/tests/ui/lint/ptr_null_checks.rs @@ -38,15 +38,15 @@ fn main() { if (&mut 8 as *mut i32).is_null() {} //~^ WARN references are not nullable if ptr::from_mut(&mut 8).is_null() {} - //~^ WARN references are not nullable + //~^ WARN call is never null if (&8 as *const i32).is_null() {} //~^ WARN references are not nullable if ptr::from_ref(&8).is_null() {} - //~^ WARN references are not nullable + //~^ WARN call is never null if ptr::from_ref(&8).cast_mut().is_null() {} - //~^ WARN references are not nullable + //~^ WARN call is never null if (ptr::from_ref(&8).cast_mut() as *mut i32).is_null() {} - //~^ WARN references are not nullable + //~^ WARN call is never null if (&8 as *const i32) == std::ptr::null() {} //~^ WARN references are not nullable let ref_num = &8; @@ -65,6 +65,12 @@ fn main() { if (&*{ static_i32() } as *const i32).is_null() {} //~^ WARN references are not nullable + // ---------------- Functions ------------------- + if ptr::NonNull::new(&mut 8).unwrap().as_ptr().is_null() {} + //~^ WARN call is never null + if ptr::NonNull::<u8>::dangling().as_ptr().is_null() {} + //~^ WARN call is never null + // ---------------------------------------------- const ZPTR: *const () = 0 as *const _; const NOT_ZPTR: *const () = 1 as *const _; diff --git a/tests/ui/lint/ptr_null_checks.stderr b/tests/ui/lint/ptr_null_checks.stderr index 3cee1804b62..0edc1b86536 100644 --- a/tests/ui/lint/ptr_null_checks.stderr +++ b/tests/ui/lint/ptr_null_checks.stderr @@ -117,13 +117,11 @@ LL | if (&mut 8 as *mut i32).is_null() {} | | | expression has type `&mut i32` -warning: references are not nullable, so checking them for null will always return false +warning: returned pointer of `from_mut` call is never null, so checking it for null will always return false --> $DIR/ptr_null_checks.rs:40:8 | LL | if ptr::from_mut(&mut 8).is_null() {} - | ^^^^^^^^^^^^^^------^^^^^^^^^^^ - | | - | expression has type `&mut i32` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: references are not nullable, so checking them for null will always return false --> $DIR/ptr_null_checks.rs:42:8 @@ -133,29 +131,23 @@ LL | if (&8 as *const i32).is_null() {} | | | expression has type `&i32` -warning: references are not nullable, so checking them for null will always return false +warning: returned pointer of `from_ref` call is never null, so checking it for null will always return false --> $DIR/ptr_null_checks.rs:44:8 | LL | if ptr::from_ref(&8).is_null() {} - | ^^^^^^^^^^^^^^--^^^^^^^^^^^ - | | - | expression has type `&i32` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ -warning: references are not nullable, so checking them for null will always return false +warning: returned pointer of `from_ref` call is never null, so checking it for null will always return false --> $DIR/ptr_null_checks.rs:46:8 | LL | if ptr::from_ref(&8).cast_mut().is_null() {} - | ^^^^^^^^^^^^^^--^^^^^^^^^^^^^^^^^^^^^^ - | | - | expression has type `&i32` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -warning: references are not nullable, so checking them for null will always return false +warning: returned pointer of `from_ref` call is never null, so checking it for null will always return false --> $DIR/ptr_null_checks.rs:48:8 | LL | if (ptr::from_ref(&8).cast_mut() as *mut i32).is_null() {} - | ^^^^^^^^^^^^^^^--^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | | - | expression has type `&i32` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: references are not nullable, so checking them for null will always return false --> $DIR/ptr_null_checks.rs:50:8 @@ -221,5 +213,17 @@ LL | if (&*{ static_i32() } as *const i32).is_null() {} | | | expression has type `&i32` -warning: 25 warnings emitted +warning: returned pointer of `as_ptr` call is never null, so checking it for null will always return false + --> $DIR/ptr_null_checks.rs:69:8 + | +LL | if ptr::NonNull::new(&mut 8).unwrap().as_ptr().is_null() {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +warning: returned pointer of `as_ptr` call is never null, so checking it for null will always return false + --> $DIR/ptr_null_checks.rs:71:8 + | +LL | if ptr::NonNull::<u8>::dangling().as_ptr().is_null() {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +warning: 27 warnings emitted diff --git a/tests/ui/match/issue-115681.rs b/tests/ui/match/issue-115681.rs new file mode 100644 index 00000000000..c41e808e170 --- /dev/null +++ b/tests/ui/match/issue-115681.rs @@ -0,0 +1,32 @@ +// run-pass +// compile-flags: -C opt-level=1 + +// Make sure LLVM does not miscompile this match. +fn main() { + enum Bits { + None = 0x00, + Low = 0x40, + High = 0x80, + Both = 0xC0, + } + + let value = Box::new(0x40u8); + let mut out = Box::new(0u8); + + let bits = match *value { + 0x00 => Bits::None, + 0x40 => Bits::Low, + 0x80 => Bits::High, + 0xC0 => Bits::Both, + _ => return, + }; + + match bits { + Bits::None | Bits::Low => { + *out = 1; + } + _ => (), + } + + assert_eq!(*out, 1); +} diff --git a/tests/ui/mir/issue-92893.rs b/tests/ui/mir/issue-92893.rs index 635050f376c..6127d267ebc 100644 --- a/tests/ui/mir/issue-92893.rs +++ b/tests/ui/mir/issue-92893.rs @@ -1,7 +1,5 @@ struct Bug<A = [(); (let a = (), 1).1]> { - //~^ `let` expressions are not supported here - //~| `let` expressions in this position are unstable [E0658] - //~| expected expression, found `let` statement + //~^ ERROR expected expression, found `let` statement a: A } diff --git a/tests/ui/mir/issue-92893.stderr b/tests/ui/mir/issue-92893.stderr index 4a0fcce31d7..6c1a9dc0317 100644 --- a/tests/ui/mir/issue-92893.stderr +++ b/tests/ui/mir/issue-92893.stderr @@ -3,24 +3,8 @@ error: expected expression, found `let` statement | LL | struct Bug<A = [(); (let a = (), 1).1]> { | ^^^ - -error: `let` expressions are not supported here - --> $DIR/issue-92893.rs:1:22 - | -LL | struct Bug<A = [(); (let a = (), 1).1]> { - | ^^^^^^^^^^ | = note: only supported directly in conditions of `if` and `while` expressions -error[E0658]: `let` expressions in this position are unstable - --> $DIR/issue-92893.rs:1:22 - | -LL | struct Bug<A = [(); (let a = (), 1).1]> { - | ^^^^^^^^^^ - | - = note: see issue #53667 <https://github.com/rust-lang/rust/issues/53667> for more information - = help: add `#![feature(let_chains)]` to the crate attributes to enable - -error: aborting due to 3 previous errors +error: aborting due to previous error -For more information about this error, try `rustc --explain E0658`. diff --git a/tests/ui/mismatched_types/cast-rfc0401.stderr b/tests/ui/mismatched_types/cast-rfc0401.stderr index 6b9ac3c5852..d63cec48917 100644 --- a/tests/ui/mismatched_types/cast-rfc0401.stderr +++ b/tests/ui/mismatched_types/cast-rfc0401.stderr @@ -82,13 +82,18 @@ error[E0606]: casting `f32` as `*const u8` is invalid LL | let _ = f as *const u8; | ^^^^^^^^^^^^^^ -error[E0054]: cannot cast as `bool` +error[E0054]: cannot cast `i32` as `bool` --> $DIR/cast-rfc0401.rs:39:13 | LL | let _ = 3_i32 as bool; - | ^^^^^^^^^^^^^ help: compare with zero instead: `3_i32 != 0` + | ^^^^^^^^^^^^^ + | +help: compare with zero instead + | +LL | let _ = 3_i32 != 0; + | ~~~~ -error[E0054]: cannot cast as `bool` +error[E0054]: cannot cast `E` as `bool` --> $DIR/cast-rfc0401.rs:40:13 | LL | let _ = E::A as bool; diff --git a/tests/ui/namespace/namespace-mix.stderr b/tests/ui/namespace/namespace-mix.stderr index 3ac5e96c574..4eff08ead42 100644 --- a/tests/ui/namespace/namespace-mix.stderr +++ b/tests/ui/namespace/namespace-mix.stderr @@ -114,6 +114,11 @@ LL | check(m1::S{}); | | | required by a bound introduced by this call | +help: this trait has no implementations, consider adding one + --> $DIR/namespace-mix.rs:20:1 + | +LL | trait Impossible {} + | ^^^^^^^^^^^^^^^^ note: required by a bound in `check` --> $DIR/namespace-mix.rs:21:13 | @@ -128,6 +133,11 @@ LL | check(m2::S{}); | | | required by a bound introduced by this call | +help: this trait has no implementations, consider adding one + --> $DIR/namespace-mix.rs:20:1 + | +LL | trait Impossible {} + | ^^^^^^^^^^^^^^^^ note: required by a bound in `check` --> $DIR/namespace-mix.rs:21:13 | @@ -142,6 +152,11 @@ LL | check(m2::S); | | | required by a bound introduced by this call | +help: this trait has no implementations, consider adding one + --> $DIR/namespace-mix.rs:20:1 + | +LL | trait Impossible {} + | ^^^^^^^^^^^^^^^^ note: required by a bound in `check` --> $DIR/namespace-mix.rs:21:13 | @@ -156,6 +171,11 @@ LL | check(xm1::S{}); | | | required by a bound introduced by this call | +help: this trait has no implementations, consider adding one + --> $DIR/namespace-mix.rs:20:1 + | +LL | trait Impossible {} + | ^^^^^^^^^^^^^^^^ note: required by a bound in `check` --> $DIR/namespace-mix.rs:21:13 | @@ -170,6 +190,11 @@ LL | check(xm2::S{}); | | | required by a bound introduced by this call | +help: this trait has no implementations, consider adding one + --> $DIR/namespace-mix.rs:20:1 + | +LL | trait Impossible {} + | ^^^^^^^^^^^^^^^^ note: required by a bound in `check` --> $DIR/namespace-mix.rs:21:13 | @@ -184,6 +209,11 @@ LL | check(xm2::S); | | | required by a bound introduced by this call | +help: this trait has no implementations, consider adding one + --> $DIR/namespace-mix.rs:20:1 + | +LL | trait Impossible {} + | ^^^^^^^^^^^^^^^^ note: required by a bound in `check` --> $DIR/namespace-mix.rs:21:13 | @@ -198,6 +228,11 @@ LL | check(m3::TS{}); | | | required by a bound introduced by this call | +help: this trait has no implementations, consider adding one + --> $DIR/namespace-mix.rs:20:1 + | +LL | trait Impossible {} + | ^^^^^^^^^^^^^^^^ note: required by a bound in `check` --> $DIR/namespace-mix.rs:21:13 | @@ -212,6 +247,11 @@ LL | check(m3::TS); | | | required by a bound introduced by this call | +help: this trait has no implementations, consider adding one + --> $DIR/namespace-mix.rs:20:1 + | +LL | trait Impossible {} + | ^^^^^^^^^^^^^^^^ note: required by a bound in `check` --> $DIR/namespace-mix.rs:21:13 | @@ -226,6 +266,11 @@ LL | check(m4::TS{}); | | | required by a bound introduced by this call | +help: this trait has no implementations, consider adding one + --> $DIR/namespace-mix.rs:20:1 + | +LL | trait Impossible {} + | ^^^^^^^^^^^^^^^^ note: required by a bound in `check` --> $DIR/namespace-mix.rs:21:13 | @@ -240,6 +285,11 @@ LL | check(m4::TS); | | | required by a bound introduced by this call | +help: this trait has no implementations, consider adding one + --> $DIR/namespace-mix.rs:20:1 + | +LL | trait Impossible {} + | ^^^^^^^^^^^^^^^^ note: required by a bound in `check` --> $DIR/namespace-mix.rs:21:13 | @@ -254,6 +304,11 @@ LL | check(xm3::TS{}); | | | required by a bound introduced by this call | +help: this trait has no implementations, consider adding one + --> $DIR/namespace-mix.rs:20:1 + | +LL | trait Impossible {} + | ^^^^^^^^^^^^^^^^ note: required by a bound in `check` --> $DIR/namespace-mix.rs:21:13 | @@ -268,6 +323,11 @@ LL | check(xm3::TS); | | | required by a bound introduced by this call | +help: this trait has no implementations, consider adding one + --> $DIR/namespace-mix.rs:20:1 + | +LL | trait Impossible {} + | ^^^^^^^^^^^^^^^^ note: required by a bound in `check` --> $DIR/namespace-mix.rs:21:13 | @@ -282,6 +342,11 @@ LL | check(xm4::TS{}); | | | required by a bound introduced by this call | +help: this trait has no implementations, consider adding one + --> $DIR/namespace-mix.rs:20:1 + | +LL | trait Impossible {} + | ^^^^^^^^^^^^^^^^ note: required by a bound in `check` --> $DIR/namespace-mix.rs:21:13 | @@ -296,6 +361,11 @@ LL | check(xm4::TS); | | | required by a bound introduced by this call | +help: this trait has no implementations, consider adding one + --> $DIR/namespace-mix.rs:20:1 + | +LL | trait Impossible {} + | ^^^^^^^^^^^^^^^^ note: required by a bound in `check` --> $DIR/namespace-mix.rs:21:13 | @@ -310,6 +380,11 @@ LL | check(m5::US{}); | | | required by a bound introduced by this call | +help: this trait has no implementations, consider adding one + --> $DIR/namespace-mix.rs:20:1 + | +LL | trait Impossible {} + | ^^^^^^^^^^^^^^^^ note: required by a bound in `check` --> $DIR/namespace-mix.rs:21:13 | @@ -324,6 +399,11 @@ LL | check(m5::US); | | | required by a bound introduced by this call | +help: this trait has no implementations, consider adding one + --> $DIR/namespace-mix.rs:20:1 + | +LL | trait Impossible {} + | ^^^^^^^^^^^^^^^^ note: required by a bound in `check` --> $DIR/namespace-mix.rs:21:13 | @@ -338,6 +418,11 @@ LL | check(m6::US{}); | | | required by a bound introduced by this call | +help: this trait has no implementations, consider adding one + --> $DIR/namespace-mix.rs:20:1 + | +LL | trait Impossible {} + | ^^^^^^^^^^^^^^^^ note: required by a bound in `check` --> $DIR/namespace-mix.rs:21:13 | @@ -352,6 +437,11 @@ LL | check(m6::US); | | | required by a bound introduced by this call | +help: this trait has no implementations, consider adding one + --> $DIR/namespace-mix.rs:20:1 + | +LL | trait Impossible {} + | ^^^^^^^^^^^^^^^^ note: required by a bound in `check` --> $DIR/namespace-mix.rs:21:13 | @@ -366,6 +456,11 @@ LL | check(xm5::US{}); | | | required by a bound introduced by this call | +help: this trait has no implementations, consider adding one + --> $DIR/namespace-mix.rs:20:1 + | +LL | trait Impossible {} + | ^^^^^^^^^^^^^^^^ note: required by a bound in `check` --> $DIR/namespace-mix.rs:21:13 | @@ -380,6 +475,11 @@ LL | check(xm5::US); | | | required by a bound introduced by this call | +help: this trait has no implementations, consider adding one + --> $DIR/namespace-mix.rs:20:1 + | +LL | trait Impossible {} + | ^^^^^^^^^^^^^^^^ note: required by a bound in `check` --> $DIR/namespace-mix.rs:21:13 | @@ -394,6 +494,11 @@ LL | check(xm6::US{}); | | | required by a bound introduced by this call | +help: this trait has no implementations, consider adding one + --> $DIR/namespace-mix.rs:20:1 + | +LL | trait Impossible {} + | ^^^^^^^^^^^^^^^^ note: required by a bound in `check` --> $DIR/namespace-mix.rs:21:13 | @@ -408,6 +513,11 @@ LL | check(xm6::US); | | | required by a bound introduced by this call | +help: this trait has no implementations, consider adding one + --> $DIR/namespace-mix.rs:20:1 + | +LL | trait Impossible {} + | ^^^^^^^^^^^^^^^^ note: required by a bound in `check` --> $DIR/namespace-mix.rs:21:13 | @@ -422,6 +532,11 @@ LL | check(m7::V{}); | | | required by a bound introduced by this call | +help: this trait has no implementations, consider adding one + --> $DIR/namespace-mix.rs:20:1 + | +LL | trait Impossible {} + | ^^^^^^^^^^^^^^^^ note: required by a bound in `check` --> $DIR/namespace-mix.rs:21:13 | @@ -436,6 +551,11 @@ LL | check(m8::V{}); | | | required by a bound introduced by this call | +help: this trait has no implementations, consider adding one + --> $DIR/namespace-mix.rs:20:1 + | +LL | trait Impossible {} + | ^^^^^^^^^^^^^^^^ note: required by a bound in `check` --> $DIR/namespace-mix.rs:21:13 | @@ -450,6 +570,11 @@ LL | check(m8::V); | | | required by a bound introduced by this call | +help: this trait has no implementations, consider adding one + --> $DIR/namespace-mix.rs:20:1 + | +LL | trait Impossible {} + | ^^^^^^^^^^^^^^^^ note: required by a bound in `check` --> $DIR/namespace-mix.rs:21:13 | @@ -464,6 +589,11 @@ LL | check(xm7::V{}); | | | required by a bound introduced by this call | +help: this trait has no implementations, consider adding one + --> $DIR/namespace-mix.rs:20:1 + | +LL | trait Impossible {} + | ^^^^^^^^^^^^^^^^ note: required by a bound in `check` --> $DIR/namespace-mix.rs:21:13 | @@ -478,6 +608,11 @@ LL | check(xm8::V{}); | | | required by a bound introduced by this call | +help: this trait has no implementations, consider adding one + --> $DIR/namespace-mix.rs:20:1 + | +LL | trait Impossible {} + | ^^^^^^^^^^^^^^^^ note: required by a bound in `check` --> $DIR/namespace-mix.rs:21:13 | @@ -492,6 +627,11 @@ LL | check(xm8::V); | | | required by a bound introduced by this call | +help: this trait has no implementations, consider adding one + --> $DIR/namespace-mix.rs:20:1 + | +LL | trait Impossible {} + | ^^^^^^^^^^^^^^^^ note: required by a bound in `check` --> $DIR/namespace-mix.rs:21:13 | @@ -506,6 +646,11 @@ LL | check(m9::TV{}); | | | required by a bound introduced by this call | +help: this trait has no implementations, consider adding one + --> $DIR/namespace-mix.rs:20:1 + | +LL | trait Impossible {} + | ^^^^^^^^^^^^^^^^ note: required by a bound in `check` --> $DIR/namespace-mix.rs:21:13 | @@ -520,6 +665,11 @@ LL | check(m9::TV); | | | required by a bound introduced by this call | +help: this trait has no implementations, consider adding one + --> $DIR/namespace-mix.rs:20:1 + | +LL | trait Impossible {} + | ^^^^^^^^^^^^^^^^ note: required by a bound in `check` --> $DIR/namespace-mix.rs:21:13 | @@ -534,6 +684,11 @@ LL | check(mA::TV{}); | | | required by a bound introduced by this call | +help: this trait has no implementations, consider adding one + --> $DIR/namespace-mix.rs:20:1 + | +LL | trait Impossible {} + | ^^^^^^^^^^^^^^^^ note: required by a bound in `check` --> $DIR/namespace-mix.rs:21:13 | @@ -548,6 +703,11 @@ LL | check(mA::TV); | | | required by a bound introduced by this call | +help: this trait has no implementations, consider adding one + --> $DIR/namespace-mix.rs:20:1 + | +LL | trait Impossible {} + | ^^^^^^^^^^^^^^^^ note: required by a bound in `check` --> $DIR/namespace-mix.rs:21:13 | @@ -562,6 +722,11 @@ LL | check(xm9::TV{}); | | | required by a bound introduced by this call | +help: this trait has no implementations, consider adding one + --> $DIR/namespace-mix.rs:20:1 + | +LL | trait Impossible {} + | ^^^^^^^^^^^^^^^^ note: required by a bound in `check` --> $DIR/namespace-mix.rs:21:13 | @@ -576,6 +741,11 @@ LL | check(xm9::TV); | | | required by a bound introduced by this call | +help: this trait has no implementations, consider adding one + --> $DIR/namespace-mix.rs:20:1 + | +LL | trait Impossible {} + | ^^^^^^^^^^^^^^^^ note: required by a bound in `check` --> $DIR/namespace-mix.rs:21:13 | @@ -590,6 +760,11 @@ LL | check(xmA::TV{}); | | | required by a bound introduced by this call | +help: this trait has no implementations, consider adding one + --> $DIR/namespace-mix.rs:20:1 + | +LL | trait Impossible {} + | ^^^^^^^^^^^^^^^^ note: required by a bound in `check` --> $DIR/namespace-mix.rs:21:13 | @@ -604,6 +779,11 @@ LL | check(xmA::TV); | | | required by a bound introduced by this call | +help: this trait has no implementations, consider adding one + --> $DIR/namespace-mix.rs:20:1 + | +LL | trait Impossible {} + | ^^^^^^^^^^^^^^^^ note: required by a bound in `check` --> $DIR/namespace-mix.rs:21:13 | @@ -618,6 +798,11 @@ LL | check(mB::UV{}); | | | required by a bound introduced by this call | +help: this trait has no implementations, consider adding one + --> $DIR/namespace-mix.rs:20:1 + | +LL | trait Impossible {} + | ^^^^^^^^^^^^^^^^ note: required by a bound in `check` --> $DIR/namespace-mix.rs:21:13 | @@ -632,6 +817,11 @@ LL | check(mB::UV); | | | required by a bound introduced by this call | +help: this trait has no implementations, consider adding one + --> $DIR/namespace-mix.rs:20:1 + | +LL | trait Impossible {} + | ^^^^^^^^^^^^^^^^ note: required by a bound in `check` --> $DIR/namespace-mix.rs:21:13 | @@ -646,6 +836,11 @@ LL | check(mC::UV{}); | | | required by a bound introduced by this call | +help: this trait has no implementations, consider adding one + --> $DIR/namespace-mix.rs:20:1 + | +LL | trait Impossible {} + | ^^^^^^^^^^^^^^^^ note: required by a bound in `check` --> $DIR/namespace-mix.rs:21:13 | @@ -660,6 +855,11 @@ LL | check(mC::UV); | | | required by a bound introduced by this call | +help: this trait has no implementations, consider adding one + --> $DIR/namespace-mix.rs:20:1 + | +LL | trait Impossible {} + | ^^^^^^^^^^^^^^^^ note: required by a bound in `check` --> $DIR/namespace-mix.rs:21:13 | @@ -674,6 +874,11 @@ LL | check(xmB::UV{}); | | | required by a bound introduced by this call | +help: this trait has no implementations, consider adding one + --> $DIR/namespace-mix.rs:20:1 + | +LL | trait Impossible {} + | ^^^^^^^^^^^^^^^^ note: required by a bound in `check` --> $DIR/namespace-mix.rs:21:13 | @@ -688,6 +893,11 @@ LL | check(xmB::UV); | | | required by a bound introduced by this call | +help: this trait has no implementations, consider adding one + --> $DIR/namespace-mix.rs:20:1 + | +LL | trait Impossible {} + | ^^^^^^^^^^^^^^^^ note: required by a bound in `check` --> $DIR/namespace-mix.rs:21:13 | @@ -702,6 +912,11 @@ LL | check(xmC::UV{}); | | | required by a bound introduced by this call | +help: this trait has no implementations, consider adding one + --> $DIR/namespace-mix.rs:20:1 + | +LL | trait Impossible {} + | ^^^^^^^^^^^^^^^^ note: required by a bound in `check` --> $DIR/namespace-mix.rs:21:13 | @@ -716,6 +931,11 @@ LL | check(xmC::UV); | | | required by a bound introduced by this call | +help: this trait has no implementations, consider adding one + --> $DIR/namespace-mix.rs:20:1 + | +LL | trait Impossible {} + | ^^^^^^^^^^^^^^^^ note: required by a bound in `check` --> $DIR/namespace-mix.rs:21:13 | diff --git a/tests/ui/nested-ty-params.rs b/tests/ui/nested-ty-params.rs index 85413acdb14..25bac1ba24b 100644 --- a/tests/ui/nested-ty-params.rs +++ b/tests/ui/nested-ty-params.rs @@ -1,4 +1,4 @@ -// error-pattern:can't use generic parameters from outer function +// error-pattern:can't use generic parameters from outer item fn hd<U>(v: Vec<U> ) -> U { fn hd1(w: [U]) -> U { return w[0]; } diff --git a/tests/ui/nested-ty-params.stderr b/tests/ui/nested-ty-params.stderr index 8f4746f5ec3..a9cdec66719 100644 --- a/tests/ui/nested-ty-params.stderr +++ b/tests/ui/nested-ty-params.stderr @@ -1,22 +1,22 @@ -error[E0401]: can't use generic parameters from outer function +error[E0401]: can't use generic parameters from outer item --> $DIR/nested-ty-params.rs:3:16 | LL | fn hd<U>(v: Vec<U> ) -> U { - | - type parameter from outer function + | - type parameter from outer item LL | fn hd1(w: [U]) -> U { return w[0]; } - | - ^ use of generic parameter from outer function + | - ^ use of generic parameter from outer item | | - | help: try using a local generic parameter instead: `<U>` + | help: try introducing a local generic parameter here: `<U>` -error[E0401]: can't use generic parameters from outer function +error[E0401]: can't use generic parameters from outer item --> $DIR/nested-ty-params.rs:3:23 | LL | fn hd<U>(v: Vec<U> ) -> U { - | - type parameter from outer function + | - type parameter from outer item LL | fn hd1(w: [U]) -> U { return w[0]; } - | - ^ use of generic parameter from outer function + | - ^ use of generic parameter from outer item | | - | help: try using a local generic parameter instead: `<U>` + | help: try introducing a local generic parameter here: `<U>` error: aborting due to 2 previous errors diff --git a/tests/ui/never_type/feature-gate-never_type_fallback.stderr b/tests/ui/never_type/feature-gate-never_type_fallback.stderr index 2db1cc4b776..56aafbb4ce8 100644 --- a/tests/ui/never_type/feature-gate-never_type_fallback.stderr +++ b/tests/ui/never_type/feature-gate-never_type_fallback.stderr @@ -8,6 +8,11 @@ LL | foo(panic!()) | | this tail expression is of type `()` | required by a bound introduced by this call | +help: this trait has no implementations, consider adding one + --> $DIR/feature-gate-never_type_fallback.rs:7:1 + | +LL | trait T {} + | ^^^^^^^ note: required by a bound in `foo` --> $DIR/feature-gate-never_type_fallback.rs:13:16 | diff --git a/tests/ui/never_type/impl_trait_fallback3.stderr b/tests/ui/never_type/impl_trait_fallback3.stderr index 5d5d216fb9b..821d141569e 100644 --- a/tests/ui/never_type/impl_trait_fallback3.stderr +++ b/tests/ui/never_type/impl_trait_fallback3.stderr @@ -3,6 +3,12 @@ error[E0277]: the trait bound `(): T` is not satisfied | LL | fn a() -> Foo { | ^^^ the trait `T` is not implemented for `()` + | +help: this trait has no implementations, consider adding one + --> $DIR/impl_trait_fallback3.rs:5:1 + | +LL | trait T { + | ^^^^^^^ error: aborting due to previous error diff --git a/tests/ui/never_type/impl_trait_fallback4.stderr b/tests/ui/never_type/impl_trait_fallback4.stderr index f2e216e9044..67421ba8da7 100644 --- a/tests/ui/never_type/impl_trait_fallback4.stderr +++ b/tests/ui/never_type/impl_trait_fallback4.stderr @@ -3,6 +3,12 @@ error[E0277]: the trait bound `(): T` is not satisfied | LL | fn foo() -> impl T { | ^^^^^^ the trait `T` is not implemented for `()` + | +help: this trait has no implementations, consider adding one + --> $DIR/impl_trait_fallback4.rs:3:1 + | +LL | trait T { + | ^^^^^^^ error: aborting due to previous error diff --git a/tests/ui/on-unimplemented/on-trait.stderr b/tests/ui/on-unimplemented/on-trait.stderr index 4b040f1ac5a..4847a1a5a61 100644 --- a/tests/ui/on-unimplemented/on-trait.stderr +++ b/tests/ui/on-unimplemented/on-trait.stderr @@ -5,6 +5,11 @@ LL | let y: Option<Vec<u8>> = collect(x.iter()); // this should give approxi | ^^^^^^^ a collection of type `Option<Vec<u8>>` cannot be built from an iterator over elements of type `&u8` | = help: the trait `MyFromIterator<&u8>` is not implemented for `Option<Vec<u8>>` +help: this trait has no implementations, consider adding one + --> $DIR/on-trait.rs:17:1 + | +LL | trait MyFromIterator<A> { + | ^^^^^^^^^^^^^^^^^^^^^^^ note: required by a bound in `collect` --> $DIR/on-trait.rs:22:39 | @@ -18,6 +23,11 @@ LL | let x: String = foobar(); | ^^^^^^ test error `String` with `u8` `_` `u32` in `Foo` | = help: the trait `Foo<u8, _, u32>` is not implemented for `String` +help: this trait has no implementations, consider adding one + --> $DIR/on-trait.rs:7:3 + | +LL | pub trait Foo<Bar, Baz, Quux> {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ note: required by a bound in `foobar` --> $DIR/on-trait.rs:12:24 | diff --git a/tests/ui/on-unimplemented/parent-label.stderr b/tests/ui/on-unimplemented/parent-label.stderr index 8cd7412fd9d..101a41512d2 100644 --- a/tests/ui/on-unimplemented/parent-label.stderr +++ b/tests/ui/on-unimplemented/parent-label.stderr @@ -8,6 +8,11 @@ LL | f(Foo {}); | | | required by a bound introduced by this call | +help: this trait has no implementations, consider adding one + --> $DIR/parent-label.rs:6:1 + | +LL | trait Trait {} + | ^^^^^^^^^^^ note: required by a bound in `f` --> $DIR/parent-label.rs:10:9 | @@ -24,6 +29,11 @@ LL | f(Foo {}); | | | required by a bound introduced by this call | +help: this trait has no implementations, consider adding one + --> $DIR/parent-label.rs:6:1 + | +LL | trait Trait {} + | ^^^^^^^^^^^ note: required by a bound in `f` --> $DIR/parent-label.rs:10:9 | @@ -41,6 +51,11 @@ LL | f(Foo {}); | | | required by a bound introduced by this call | +help: this trait has no implementations, consider adding one + --> $DIR/parent-label.rs:6:1 + | +LL | trait Trait {} + | ^^^^^^^^^^^ note: required by a bound in `f` --> $DIR/parent-label.rs:10:9 | @@ -58,6 +73,11 @@ LL | f(Foo {}); | | | required by a bound introduced by this call | +help: this trait has no implementations, consider adding one + --> $DIR/parent-label.rs:6:1 + | +LL | trait Trait {} + | ^^^^^^^^^^^ note: required by a bound in `f` --> $DIR/parent-label.rs:10:9 | diff --git a/tests/ui/parser/issues/issue-115780-pat-lt-bracket-in-macro-call.rs b/tests/ui/parser/issues/issue-115780-pat-lt-bracket-in-macro-call.rs new file mode 100644 index 00000000000..3421333b8a0 --- /dev/null +++ b/tests/ui/parser/issues/issue-115780-pat-lt-bracket-in-macro-call.rs @@ -0,0 +1,21 @@ +// Regression test for issue #115780. +// Ensure that we don't emit a parse error for the token sequence `Ident "<" Ty` in pattern position +// if we are inside a macro call since it can be valid input for a subsequent macro rule. +// See also #103534. + +// check-pass + +macro_rules! mdo { + ($p: pat =<< $e: expr ; $( $t: tt )*) => { + $e.and_then(|$p| mdo! { $( $t )* }) + }; + (ret<$ty: ty> $e: expr;) => { Some::<$ty>($e) }; +} + +fn main() { + mdo! { + x_val =<< Some(0); + y_val =<< Some(1); + ret<(i32, i32)> (x_val, y_val); + }; +} diff --git a/tests/ui/pattern/issue-114896.rs b/tests/ui/pattern/issue-114896.rs new file mode 100644 index 00000000000..cde37f658d6 --- /dev/null +++ b/tests/ui/pattern/issue-114896.rs @@ -0,0 +1,7 @@ +fn main() { + fn x(a: &char) { + let &b = a; + b.make_ascii_uppercase(); +//~^ cannot borrow `b` as mutable, as it is not declared as mutable + } +} diff --git a/tests/ui/pattern/issue-114896.stderr b/tests/ui/pattern/issue-114896.stderr new file mode 100644 index 00000000000..ffeb7bc1365 --- /dev/null +++ b/tests/ui/pattern/issue-114896.stderr @@ -0,0 +1,11 @@ +error[E0596]: cannot borrow `b` as mutable, as it is not declared as mutable + --> $DIR/issue-114896.rs:4:9 + | +LL | let &b = a; + | -- help: consider changing this to be mutable: `&(mut b)` +LL | b.make_ascii_uppercase(); + | ^ cannot borrow as mutable + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0596`. diff --git a/tests/ui/proc-macro/bad-projection.stderr b/tests/ui/proc-macro/bad-projection.stderr index 8a8246376fe..8716defa17a 100644 --- a/tests/ui/proc-macro/bad-projection.stderr +++ b/tests/ui/proc-macro/bad-projection.stderr @@ -3,6 +3,12 @@ error[E0277]: the trait bound `(): Project` is not satisfied | LL | pub fn uwu() -> <() as Project>::Assoc {} | ^^^^^^^^^^^^^^^^^^^^^^ the trait `Project` is not implemented for `()` + | +help: this trait has no implementations, consider adding one + --> $DIR/bad-projection.rs:9:1 + | +LL | trait Project { + | ^^^^^^^^^^^^^ error: aborting due to previous error diff --git a/tests/ui/range/range-1.stderr b/tests/ui/range/range-1.stderr index ecfc56961ee..96c1ffb2f7e 100644 --- a/tests/ui/range/range-1.stderr +++ b/tests/ui/range/range-1.stderr @@ -19,7 +19,7 @@ LL | for i in false..true {} i64 i128 usize - and 6 others + and 8 others = note: required for `std::ops::Range<bool>` to implement `Iterator` = note: required for `std::ops::Range<bool>` to implement `IntoIterator` diff --git a/tests/ui/repr/repr-transparent-non-exhaustive.rs b/tests/ui/repr/repr-transparent-non-exhaustive.rs index 506f1dcf3fc..84dd3f49239 100644 --- a/tests/ui/repr/repr-transparent-non-exhaustive.rs +++ b/tests/ui/repr/repr-transparent-non-exhaustive.rs @@ -93,4 +93,44 @@ pub struct T16(Sized, ExternalIndirection<NonExhaustiveVariant>); //~^ ERROR zero-sized fields in `repr(transparent)` cannot contain external non-exhaustive types //~| WARN this was previously accepted by the compiler +#[repr(transparent)] +pub struct T17(NonExhaustive, Sized); +//~^ ERROR zero-sized fields in `repr(transparent)` cannot contain external non-exhaustive types +//~| WARN this was previously accepted by the compiler + +#[repr(transparent)] +pub struct T18(NonExhaustive, NonExhaustive); +//~^ ERROR zero-sized fields in `repr(transparent)` cannot contain external non-exhaustive types +//~| WARN this was previously accepted by the compiler + +#[repr(transparent)] +pub struct T19(NonExhaustive, Private); +//~^ ERROR zero-sized fields in `repr(transparent)` cannot contain external non-exhaustive types +//~| WARN this was previously accepted by the compiler + +#[repr(transparent)] +pub struct T19Flipped(Private, NonExhaustive); +//~^ ERROR zero-sized fields in `repr(transparent)` cannot contain external non-exhaustive types +//~| WARN this was previously accepted by the compiler + +#[repr(transparent)] +pub struct T20(NonExhaustive); +// Okay, since it's the only field. + +#[repr(transparent)] +pub struct T21(NonExhaustive, InternalNonExhaustive); +// Okay, since there's only 1 foreign non-exhaustive type. + +#[repr(transparent)] +pub struct T21Flipped(InternalNonExhaustive, NonExhaustive); +// Okay, since there's only 1 foreign non-exhaustive type. + +#[repr(transparent)] +pub struct T22(NonExhaustive, InternalPrivate); +// Okay, since there's only 1 foreign non-exhaustive type. + +#[repr(transparent)] +pub struct T22Flipped(InternalPrivate, NonExhaustive); +// Okay, since there's only 1 foreign non-exhaustive type. + fn main() {} diff --git a/tests/ui/repr/repr-transparent-non-exhaustive.stderr b/tests/ui/repr/repr-transparent-non-exhaustive.stderr index 16edf59c7cc..808b9bc986d 100644 --- a/tests/ui/repr/repr-transparent-non-exhaustive.stderr +++ b/tests/ui/repr/repr-transparent-non-exhaustive.stderr @@ -123,5 +123,45 @@ LL | pub struct T16(Sized, ExternalIndirection<NonExhaustiveVariant>); = note: for more information, see issue #78586 <https://github.com/rust-lang/rust/issues/78586> = note: this enum contains `NonExhaustiveVariant`, which is marked with `#[non_exhaustive]`, and makes it not a breaking change to become non-zero-sized in the future. -error: aborting due to 12 previous errors +error: zero-sized fields in `repr(transparent)` cannot contain external non-exhaustive types + --> $DIR/repr-transparent-non-exhaustive.rs:97:16 + | +LL | pub struct T17(NonExhaustive, Sized); + | ^^^^^^^^^^^^^ + | + = 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 #78586 <https://github.com/rust-lang/rust/issues/78586> + = note: this struct contains `NonExhaustive`, which is marked with `#[non_exhaustive]`, and makes it not a breaking change to become non-zero-sized in the future. + +error: zero-sized fields in `repr(transparent)` cannot contain external non-exhaustive types + --> $DIR/repr-transparent-non-exhaustive.rs:102:31 + | +LL | pub struct T18(NonExhaustive, NonExhaustive); + | ^^^^^^^^^^^^^ + | + = 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 #78586 <https://github.com/rust-lang/rust/issues/78586> + = note: this struct contains `NonExhaustive`, which is marked with `#[non_exhaustive]`, and makes it not a breaking change to become non-zero-sized in the future. + +error: zero-sized fields in `repr(transparent)` cannot contain external non-exhaustive types + --> $DIR/repr-transparent-non-exhaustive.rs:107:31 + | +LL | pub struct T19(NonExhaustive, Private); + | ^^^^^^^ + | + = 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 #78586 <https://github.com/rust-lang/rust/issues/78586> + = note: this struct contains `Private`, which contains private fields, and makes it not a breaking change to become non-zero-sized in the future. + +error: zero-sized fields in `repr(transparent)` cannot contain external non-exhaustive types + --> $DIR/repr-transparent-non-exhaustive.rs:112:32 + | +LL | pub struct T19Flipped(Private, NonExhaustive); + | ^^^^^^^^^^^^^ + | + = 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 #78586 <https://github.com/rust-lang/rust/issues/78586> + = note: this struct contains `NonExhaustive`, which is marked with `#[non_exhaustive]`, and makes it not a breaking change to become non-zero-sized in the future. + +error: aborting due to 16 previous errors diff --git a/tests/ui/repr/repr-transparent.rs b/tests/ui/repr/repr-transparent.rs index 8c9d1639c0a..87cf59ce9af 100644 --- a/tests/ui/repr/repr-transparent.rs +++ b/tests/ui/repr/repr-transparent.rs @@ -23,23 +23,26 @@ struct ContainsMultipleZst(PhantomData<*const i32>, NoFields); struct ContainsZstAndNonZst((), [i32; 2]); #[repr(transparent)] -struct MultipleNonZst(u8, u8); //~ ERROR needs at most one non-zero-sized field +struct MultipleNonZst(u8, u8); //~ ERROR needs at most one field with non-trivial size or alignment trait Mirror { type It: ?Sized; } impl<T: ?Sized> Mirror for T { type It = Self; } #[repr(transparent)] pub struct StructWithProjection(f32, <f32 as Mirror>::It); -//~^ ERROR needs at most one non-zero-sized field +//~^ ERROR needs at most one field with non-trivial size or alignment #[repr(transparent)] -struct NontrivialAlignZst(u32, [u16; 0]); //~ ERROR alignment larger than 1 +struct NontrivialAlignZst(u32, [u16; 0]); //~ ERROR needs at most one field with non-trivial size or alignment #[repr(align(32))] struct ZstAlign32<T>(PhantomData<T>); #[repr(transparent)] -struct GenericAlign<T>(ZstAlign32<T>, u32); //~ ERROR alignment larger than 1 +struct GenericAlign<T>(ZstAlign32<T>, u32); //~ ERROR needs at most one field with non-trivial size or alignment + +#[repr(transparent)] +struct WrapsZstWithAlignment([i32; 0]); #[repr(transparent)] //~ ERROR unsupported representation for zero-variant enum enum Void {} //~ ERROR transparent enum needs exactly one variant, but has 0 @@ -58,7 +61,7 @@ enum UnitFieldEnum { enum TooManyFieldsEnum { Foo(u32, String), } -//~^^^ ERROR transparent enum needs at most one non-zero-sized field, but has 2 +//~^^^ ERROR transparent enum needs at most one field with non-trivial size or alignment, but has 2 #[repr(transparent)] enum MultipleVariants { //~ ERROR transparent enum needs exactly one variant, but has 2 @@ -67,13 +70,13 @@ enum MultipleVariants { //~ ERROR transparent enum needs exactly one variant, bu } #[repr(transparent)] -enum NontrivialAlignZstEnum { - Foo(u32, [u16; 0]), //~ ERROR alignment larger than 1 +enum NontrivialAlignZstEnum { //~ ERROR needs at most one field with non-trivial size or alignment + Foo(u32, [u16; 0]), } #[repr(transparent)] -enum GenericAlignEnum<T> { - Foo { bar: ZstAlign32<T>, baz: u32 } //~ ERROR alignment larger than 1 +enum GenericAlignEnum<T> { //~ ERROR needs at most one field with non-trivial size or alignment + Foo { bar: ZstAlign32<T>, baz: u32 } } #[repr(transparent)] @@ -82,7 +85,7 @@ union UnitUnion { } #[repr(transparent)] -union TooManyFields { //~ ERROR transparent union needs at most one non-zero-sized field, but has 2 +union TooManyFields { //~ ERROR transparent union needs at most one field with non-trivial size or alignment, but has 2 u: u32, s: i32 } diff --git a/tests/ui/repr/repr-transparent.stderr b/tests/ui/repr/repr-transparent.stderr index 028fc25db46..d0c78a8418a 100644 --- a/tests/ui/repr/repr-transparent.stderr +++ b/tests/ui/repr/repr-transparent.stderr @@ -1,35 +1,41 @@ -error[E0690]: transparent struct needs at most one non-zero-sized field, but has 2 +error[E0690]: transparent struct needs at most one field with non-trivial size or alignment, but has 2 --> $DIR/repr-transparent.rs:26:1 | LL | struct MultipleNonZst(u8, u8); - | ^^^^^^^^^^^^^^^^^^^^^ -- -- this field is non-zero-sized + | ^^^^^^^^^^^^^^^^^^^^^ -- -- this field has non-zero size or requires alignment | | | - | | this field is non-zero-sized - | needs at most one non-zero-sized field, but has 2 + | | this field has non-zero size or requires alignment + | needs at most one field with non-trivial size or alignment, but has 2 -error[E0690]: transparent struct needs at most one non-zero-sized field, but has 2 +error[E0690]: transparent struct needs at most one field with non-trivial size or alignment, but has 2 --> $DIR/repr-transparent.rs:32:1 | LL | pub struct StructWithProjection(f32, <f32 as Mirror>::It); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ --- ------------------- this field is non-zero-sized + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ --- ------------------- this field has non-zero size or requires alignment | | | - | | this field is non-zero-sized - | needs at most one non-zero-sized field, but has 2 + | | this field has non-zero size or requires alignment + | needs at most one field with non-trivial size or alignment, but has 2 -error[E0691]: zero-sized field in transparent struct has alignment larger than 1 - --> $DIR/repr-transparent.rs:36:32 +error[E0690]: transparent struct needs at most one field with non-trivial size or alignment, but has 2 + --> $DIR/repr-transparent.rs:36:1 | LL | struct NontrivialAlignZst(u32, [u16; 0]); - | ^^^^^^^^ has alignment of 2, which is larger than 1 + | ^^^^^^^^^^^^^^^^^^^^^^^^^ --- -------- this field has non-zero size or requires alignment + | | | + | | this field has non-zero size or requires alignment + | needs at most one field with non-trivial size or alignment, but has 2 -error[E0691]: zero-sized field in transparent struct has alignment larger than 1 - --> $DIR/repr-transparent.rs:42:24 +error[E0690]: transparent struct needs at most one field with non-trivial size or alignment, but has 2 + --> $DIR/repr-transparent.rs:42:1 | LL | struct GenericAlign<T>(ZstAlign32<T>, u32); - | ^^^^^^^^^^^^^ has alignment of 32, which is larger than 1 + | ^^^^^^^^^^^^^^^^^^^^^^ ------------- --- this field has non-zero size or requires alignment + | | | + | | this field has non-zero size or requires alignment + | needs at most one field with non-trivial size or alignment, but has 2 error[E0084]: unsupported representation for zero-variant enum - --> $DIR/repr-transparent.rs:44:1 + --> $DIR/repr-transparent.rs:47:1 | LL | #[repr(transparent)] | ^^^^^^^^^^^^^^^^^^^^ @@ -37,23 +43,23 @@ LL | enum Void {} | --------- zero-variant enum error[E0731]: transparent enum needs exactly one variant, but has 0 - --> $DIR/repr-transparent.rs:45:1 + --> $DIR/repr-transparent.rs:48:1 | LL | enum Void {} | ^^^^^^^^^ needs exactly one variant, but has 0 -error[E0690]: the variant of a transparent enum needs at most one non-zero-sized field, but has 2 - --> $DIR/repr-transparent.rs:58:1 +error[E0690]: the variant of a transparent enum needs at most one field with non-trivial size or alignment, but has 2 + --> $DIR/repr-transparent.rs:61:1 | LL | enum TooManyFieldsEnum { - | ^^^^^^^^^^^^^^^^^^^^^^ needs at most one non-zero-sized field, but has 2 + | ^^^^^^^^^^^^^^^^^^^^^^ needs at most one field with non-trivial size or alignment, but has 2 LL | Foo(u32, String), - | --- ------ this field is non-zero-sized + | --- ------ this field has non-zero size or requires alignment | | - | this field is non-zero-sized + | this field has non-zero size or requires alignment error[E0731]: transparent enum needs exactly one variant, but has 2 - --> $DIR/repr-transparent.rs:64:1 + --> $DIR/repr-transparent.rs:67:1 | LL | enum MultipleVariants { | ^^^^^^^^^^^^^^^^^^^^^ needs exactly one variant, but has 2 @@ -62,29 +68,37 @@ LL | Foo(String), LL | Bar, | --- too many variants in `MultipleVariants` -error[E0691]: zero-sized field in transparent enum has alignment larger than 1 - --> $DIR/repr-transparent.rs:71:14 +error[E0690]: the variant of a transparent enum needs at most one field with non-trivial size or alignment, but has 2 + --> $DIR/repr-transparent.rs:73:1 | +LL | enum NontrivialAlignZstEnum { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ needs at most one field with non-trivial size or alignment, but has 2 LL | Foo(u32, [u16; 0]), - | ^^^^^^^^ has alignment of 2, which is larger than 1 + | --- -------- this field has non-zero size or requires alignment + | | + | this field has non-zero size or requires alignment -error[E0691]: zero-sized field in transparent enum has alignment larger than 1 - --> $DIR/repr-transparent.rs:76:11 +error[E0690]: the variant of a transparent enum needs at most one field with non-trivial size or alignment, but has 2 + --> $DIR/repr-transparent.rs:78:1 | +LL | enum GenericAlignEnum<T> { + | ^^^^^^^^^^^^^^^^^^^^^^^^ needs at most one field with non-trivial size or alignment, but has 2 LL | Foo { bar: ZstAlign32<T>, baz: u32 } - | ^^^^^^^^^^^^^^^^^^ has alignment of 32, which is larger than 1 + | ------------------ -------- this field has non-zero size or requires alignment + | | + | this field has non-zero size or requires alignment -error[E0690]: transparent union needs at most one non-zero-sized field, but has 2 - --> $DIR/repr-transparent.rs:85:1 +error[E0690]: transparent union needs at most one field with non-trivial size or alignment, but has 2 + --> $DIR/repr-transparent.rs:88:1 | LL | union TooManyFields { - | ^^^^^^^^^^^^^^^^^^^ needs at most one non-zero-sized field, but has 2 + | ^^^^^^^^^^^^^^^^^^^ needs at most one field with non-trivial size or alignment, but has 2 LL | u: u32, - | ------ this field is non-zero-sized + | ------ this field has non-zero size or requires alignment LL | s: i32 - | ------ this field is non-zero-sized + | ------ this field has non-zero size or requires alignment error: aborting due to 11 previous errors -Some errors have detailed explanations: E0084, E0690, E0691, E0731. +Some errors have detailed explanations: E0084, E0690, E0731. For more information about an error, try `rustc --explain E0084`. diff --git a/tests/ui/resolve/bad-type-env-capture.stderr b/tests/ui/resolve/bad-type-env-capture.stderr index b6282c2d070..941b6b7a68c 100644 --- a/tests/ui/resolve/bad-type-env-capture.stderr +++ b/tests/ui/resolve/bad-type-env-capture.stderr @@ -1,12 +1,12 @@ -error[E0401]: can't use generic parameters from outer function +error[E0401]: can't use generic parameters from outer item --> $DIR/bad-type-env-capture.rs:2:15 | LL | fn foo<T>() { - | - type parameter from outer function + | - type parameter from outer item LL | fn bar(b: T) { } - | - ^ use of generic parameter from outer function + | - ^ use of generic parameter from outer item | | - | help: try using a local generic parameter instead: `<T>` + | help: try introducing a local generic parameter here: `<T>` error: aborting due to previous error diff --git a/tests/ui/resolve/generic-params-from-outer-item-in-const-item.default.stderr b/tests/ui/resolve/generic-params-from-outer-item-in-const-item.default.stderr new file mode 100644 index 00000000000..4f853829279 --- /dev/null +++ b/tests/ui/resolve/generic-params-from-outer-item-in-const-item.default.stderr @@ -0,0 +1,28 @@ +error[E0401]: can't use generic parameters from outer item + --> $DIR/generic-params-from-outer-item-in-const-item.rs:12:20 + | +LL | fn outer<T: Tr>() { // outer function + | - type parameter from outer item +LL | const K: u32 = T::C; + | ^^^^ use of generic parameter from outer item + +error[E0401]: can't use generic parameters from outer item + --> $DIR/generic-params-from-outer-item-in-const-item.rs:19:24 + | +LL | impl<T> Tr for T { // outer impl block + | - type parameter from outer item +LL | const C: u32 = { +LL | const I: u32 = T::C; + | ^^^^ use of generic parameter from outer item + +error[E0401]: can't use generic parameters from outer item + --> $DIR/generic-params-from-outer-item-in-const-item.rs:27:20 + | +LL | struct S<T: Tr>(U32<{ // outer struct + | - type parameter from outer item +LL | const _: u32 = T::C; + | ^^^^ use of generic parameter from outer item + +error: aborting due to 3 previous errors + +For more information about this error, try `rustc --explain E0401`. diff --git a/tests/ui/resolve/generic-params-from-outer-item-in-const-item.generic_const_items.stderr b/tests/ui/resolve/generic-params-from-outer-item-in-const-item.generic_const_items.stderr new file mode 100644 index 00000000000..1cb55842bc6 --- /dev/null +++ b/tests/ui/resolve/generic-params-from-outer-item-in-const-item.generic_const_items.stderr @@ -0,0 +1,34 @@ +error[E0401]: can't use generic parameters from outer item + --> $DIR/generic-params-from-outer-item-in-const-item.rs:12:20 + | +LL | fn outer<T: Tr>() { // outer function + | - type parameter from outer item +LL | const K: u32 = T::C; + | - ^^^^ use of generic parameter from outer item + | | + | help: try introducing a local generic parameter here: `<T>` + +error[E0401]: can't use generic parameters from outer item + --> $DIR/generic-params-from-outer-item-in-const-item.rs:19:24 + | +LL | impl<T> Tr for T { // outer impl block + | - type parameter from outer item +LL | const C: u32 = { +LL | const I: u32 = T::C; + | - ^^^^ use of generic parameter from outer item + | | + | help: try introducing a local generic parameter here: `<T>` + +error[E0401]: can't use generic parameters from outer item + --> $DIR/generic-params-from-outer-item-in-const-item.rs:27:20 + | +LL | struct S<T: Tr>(U32<{ // outer struct + | - type parameter from outer item +LL | const _: u32 = T::C; + | - ^^^^ use of generic parameter from outer item + | | + | help: try introducing a local generic parameter here: `<T>` + +error: aborting due to 3 previous errors + +For more information about this error, try `rustc --explain E0401`. diff --git a/tests/ui/resolve/generic-params-from-outer-item-in-const-item.rs b/tests/ui/resolve/generic-params-from-outer-item-in-const-item.rs new file mode 100644 index 00000000000..e5647d72cba --- /dev/null +++ b/tests/ui/resolve/generic-params-from-outer-item-in-const-item.rs @@ -0,0 +1,39 @@ +// Regression test for issue #115720. +// If a const item contains generic params from an outer items, only suggest +// turning the const item generic if the feature `generic_const_items` is enabled. + +// revisions: default generic_const_items + +#![cfg_attr(generic_const_items, feature(generic_const_items))] +#![feature(generic_const_exprs)] // only used for the test case "outer struct" +#![allow(incomplete_features)] + +fn outer<T: Tr>() { // outer function + const K: u32 = T::C; + //~^ ERROR can't use generic parameters from outer item + //[generic_const_items]~| HELP try introducing a local generic parameter here +} + +impl<T> Tr for T { // outer impl block + const C: u32 = { + const I: u32 = T::C; + //~^ ERROR can't use generic parameters from outer item + //[generic_const_items]~| HELP try introducing a local generic parameter here + I + }; +} + +struct S<T: Tr>(U32<{ // outer struct + const _: u32 = T::C; + //~^ ERROR can't use generic parameters from outer item + //[generic_const_items]~| HELP try introducing a local generic parameter here + 0 +}>); + +trait Tr { + const C: u32; +} + +struct U32<const N: u32>; + +fn main() {} diff --git a/tests/ui/resolve/issue-12796.rs b/tests/ui/resolve/issue-12796.rs index 942d6b9a568..de3e73437f0 100644 --- a/tests/ui/resolve/issue-12796.rs +++ b/tests/ui/resolve/issue-12796.rs @@ -1,7 +1,7 @@ trait Trait { fn outer(&self) { fn inner(_: &Self) { - //~^ ERROR can't use generic parameters from outer function + //~^ ERROR can't use generic parameters from outer item } } } diff --git a/tests/ui/resolve/issue-12796.stderr b/tests/ui/resolve/issue-12796.stderr index a01fd2d6542..ef59d00360b 100644 --- a/tests/ui/resolve/issue-12796.stderr +++ b/tests/ui/resolve/issue-12796.stderr @@ -1,10 +1,10 @@ -error[E0401]: can't use generic parameters from outer function +error[E0401]: can't use generic parameters from outer item --> $DIR/issue-12796.rs:3:22 | LL | fn inner(_: &Self) { | ^^^^ | | - | use of generic parameter from outer function + | use of generic parameter from outer item | can't use `Self` here error: aborting due to previous error diff --git a/tests/ui/resolve/issue-3021-c.rs b/tests/ui/resolve/issue-3021-c.rs index 94ed1fdf781..bd21d124423 100644 --- a/tests/ui/resolve/issue-3021-c.rs +++ b/tests/ui/resolve/issue-3021-c.rs @@ -1,8 +1,8 @@ fn siphash<T>() { trait U { - fn g(&self, x: T) -> T; //~ ERROR can't use generic parameters from outer function - //~^ ERROR can't use generic parameters from outer function + fn g(&self, x: T) -> T; //~ ERROR can't use generic parameters from outer item + //~^ ERROR can't use generic parameters from outer item } } diff --git a/tests/ui/resolve/issue-3021-c.stderr b/tests/ui/resolve/issue-3021-c.stderr index 5176efc3a6b..537bbaf7b6a 100644 --- a/tests/ui/resolve/issue-3021-c.stderr +++ b/tests/ui/resolve/issue-3021-c.stderr @@ -1,24 +1,24 @@ -error[E0401]: can't use generic parameters from outer function +error[E0401]: can't use generic parameters from outer item --> $DIR/issue-3021-c.rs:4:24 | LL | fn siphash<T>() { - | - type parameter from outer function + | - type parameter from outer item LL | LL | trait U { - | - help: try using a local generic parameter instead: `<T>` + | - help: try introducing a local generic parameter here: `<T>` LL | fn g(&self, x: T) -> T; - | ^ use of generic parameter from outer function + | ^ use of generic parameter from outer item -error[E0401]: can't use generic parameters from outer function +error[E0401]: can't use generic parameters from outer item --> $DIR/issue-3021-c.rs:4:30 | LL | fn siphash<T>() { - | - type parameter from outer function + | - type parameter from outer item LL | LL | trait U { - | - help: try using a local generic parameter instead: `<T>` + | - help: try introducing a local generic parameter here: `<T>` LL | fn g(&self, x: T) -> T; - | ^ use of generic parameter from outer function + | ^ use of generic parameter from outer item error: aborting due to 2 previous errors diff --git a/tests/ui/resolve/issue-65025-extern-static-parent-generics.rs b/tests/ui/resolve/issue-65025-extern-static-parent-generics.rs index ce45f630e48..4fa3f12d024 100644 --- a/tests/ui/resolve/issue-65025-extern-static-parent-generics.rs +++ b/tests/ui/resolve/issue-65025-extern-static-parent-generics.rs @@ -1,7 +1,7 @@ unsafe fn foo<A>() { extern "C" { static baz: *const A; - //~^ ERROR can't use generic parameters from outer function + //~^ ERROR can't use generic parameters from outer item } let bar: *const u64 = core::mem::transmute(&baz); diff --git a/tests/ui/resolve/issue-65025-extern-static-parent-generics.stderr b/tests/ui/resolve/issue-65025-extern-static-parent-generics.stderr index 6bbf76dd1fb..3e9c3fd11b7 100644 --- a/tests/ui/resolve/issue-65025-extern-static-parent-generics.stderr +++ b/tests/ui/resolve/issue-65025-extern-static-parent-generics.stderr @@ -1,11 +1,11 @@ -error[E0401]: can't use generic parameters from outer function +error[E0401]: can't use generic parameters from outer item --> $DIR/issue-65025-extern-static-parent-generics.rs:3:28 | LL | unsafe fn foo<A>() { - | - type parameter from outer function + | - type parameter from outer item LL | extern "C" { LL | static baz: *const A; - | ^ use of generic parameter from outer function + | ^ use of generic parameter from outer item error: aborting due to previous error diff --git a/tests/ui/resolve/issue-65035-static-with-parent-generics.rs b/tests/ui/resolve/issue-65035-static-with-parent-generics.rs index f96c04841dd..bc99584a8d2 100644 --- a/tests/ui/resolve/issue-65035-static-with-parent-generics.rs +++ b/tests/ui/resolve/issue-65035-static-with-parent-generics.rs @@ -1,26 +1,26 @@ fn f<T>() { extern "C" { static a: *const T; - //~^ ERROR can't use generic parameters from outer function + //~^ ERROR can't use generic parameters from outer item } } fn g<T: Default>() { static a: *const T = Default::default(); - //~^ ERROR can't use generic parameters from outer function + //~^ ERROR can't use generic parameters from outer item } fn h<const N: usize>() { extern "C" { static a: [u8; N]; - //~^ ERROR can't use generic parameters from outer function + //~^ ERROR can't use generic parameters from outer item } } fn i<const N: usize>() { static a: [u8; N] = [0; N]; - //~^ ERROR can't use generic parameters from outer function - //~| ERROR can't use generic parameters from outer function + //~^ ERROR can't use generic parameters from outer item + //~| ERROR can't use generic parameters from outer item } fn main() {} diff --git a/tests/ui/resolve/issue-65035-static-with-parent-generics.stderr b/tests/ui/resolve/issue-65035-static-with-parent-generics.stderr index 7ed572f80b8..f1fe1a6002c 100644 --- a/tests/ui/resolve/issue-65035-static-with-parent-generics.stderr +++ b/tests/ui/resolve/issue-65035-static-with-parent-generics.stderr @@ -1,44 +1,44 @@ -error[E0401]: can't use generic parameters from outer function +error[E0401]: can't use generic parameters from outer item --> $DIR/issue-65035-static-with-parent-generics.rs:3:26 | LL | fn f<T>() { - | - type parameter from outer function + | - type parameter from outer item LL | extern "C" { LL | static a: *const T; - | ^ use of generic parameter from outer function + | ^ use of generic parameter from outer item -error[E0401]: can't use generic parameters from outer function +error[E0401]: can't use generic parameters from outer item --> $DIR/issue-65035-static-with-parent-generics.rs:9:22 | LL | fn g<T: Default>() { - | - type parameter from outer function + | - type parameter from outer item LL | static a: *const T = Default::default(); - | ^ use of generic parameter from outer function + | ^ use of generic parameter from outer item -error[E0401]: can't use generic parameters from outer function +error[E0401]: can't use generic parameters from outer item --> $DIR/issue-65035-static-with-parent-generics.rs:15:24 | LL | fn h<const N: usize>() { - | - const parameter from outer function + | - const parameter from outer item LL | extern "C" { LL | static a: [u8; N]; - | ^ use of generic parameter from outer function + | ^ use of generic parameter from outer item -error[E0401]: can't use generic parameters from outer function +error[E0401]: can't use generic parameters from outer item --> $DIR/issue-65035-static-with-parent-generics.rs:21:20 | LL | fn i<const N: usize>() { - | - const parameter from outer function + | - const parameter from outer item LL | static a: [u8; N] = [0; N]; - | ^ use of generic parameter from outer function + | ^ use of generic parameter from outer item -error[E0401]: can't use generic parameters from outer function +error[E0401]: can't use generic parameters from outer item --> $DIR/issue-65035-static-with-parent-generics.rs:21:29 | LL | fn i<const N: usize>() { - | - const parameter from outer function + | - const parameter from outer item LL | static a: [u8; N] = [0; N]; - | ^ use of generic parameter from outer function + | ^ use of generic parameter from outer item error: aborting due to 5 previous errors diff --git a/tests/ui/resolve/resolve-type-param-in-item-in-trait.rs b/tests/ui/resolve/resolve-type-param-in-item-in-trait.rs index c77a66524f7..2d5f34c62a6 100644 --- a/tests/ui/resolve/resolve-type-param-in-item-in-trait.rs +++ b/tests/ui/resolve/resolve-type-param-in-item-in-trait.rs @@ -6,7 +6,7 @@ trait TraitA<A> { fn outer(&self) { enum Foo<B> { Variance(A) - //~^ ERROR can't use generic parameters from outer function + //~^ ERROR can't use generic parameters from outer item } } } @@ -14,21 +14,21 @@ trait TraitA<A> { trait TraitB<A> { fn outer(&self) { struct Foo<B>(A); - //~^ ERROR can't use generic parameters from outer function + //~^ ERROR can't use generic parameters from outer item } } trait TraitC<A> { fn outer(&self) { struct Foo<B> { a: A } - //~^ ERROR can't use generic parameters from outer function + //~^ ERROR can't use generic parameters from outer item } } trait TraitD<A> { fn outer(&self) { fn foo<B>(a: A) { } - //~^ ERROR can't use generic parameters from outer function + //~^ ERROR can't use generic parameters from outer item } } diff --git a/tests/ui/resolve/resolve-type-param-in-item-in-trait.stderr b/tests/ui/resolve/resolve-type-param-in-item-in-trait.stderr index 0a6d1cc3bcd..1ab56fdc504 100644 --- a/tests/ui/resolve/resolve-type-param-in-item-in-trait.stderr +++ b/tests/ui/resolve/resolve-type-param-in-item-in-trait.stderr @@ -1,46 +1,46 @@ -error[E0401]: can't use generic parameters from outer function +error[E0401]: can't use generic parameters from outer item --> $DIR/resolve-type-param-in-item-in-trait.rs:8:22 | LL | trait TraitA<A> { - | - type parameter from outer function + | - type parameter from outer item LL | fn outer(&self) { LL | enum Foo<B> { - | - help: try using a local generic parameter instead: `A,` + | - help: try introducing a local generic parameter here: `A,` LL | Variance(A) - | ^ use of generic parameter from outer function + | ^ use of generic parameter from outer item -error[E0401]: can't use generic parameters from outer function +error[E0401]: can't use generic parameters from outer item --> $DIR/resolve-type-param-in-item-in-trait.rs:16:23 | LL | trait TraitB<A> { - | - type parameter from outer function + | - type parameter from outer item LL | fn outer(&self) { LL | struct Foo<B>(A); - | - ^ use of generic parameter from outer function + | - ^ use of generic parameter from outer item | | - | help: try using a local generic parameter instead: `A,` + | help: try introducing a local generic parameter here: `A,` -error[E0401]: can't use generic parameters from outer function +error[E0401]: can't use generic parameters from outer item --> $DIR/resolve-type-param-in-item-in-trait.rs:23:28 | LL | trait TraitC<A> { - | - type parameter from outer function + | - type parameter from outer item LL | fn outer(&self) { LL | struct Foo<B> { a: A } - | - ^ use of generic parameter from outer function + | - ^ use of generic parameter from outer item | | - | help: try using a local generic parameter instead: `A,` + | help: try introducing a local generic parameter here: `A,` -error[E0401]: can't use generic parameters from outer function +error[E0401]: can't use generic parameters from outer item --> $DIR/resolve-type-param-in-item-in-trait.rs:30:22 | LL | trait TraitD<A> { - | - type parameter from outer function + | - type parameter from outer item LL | fn outer(&self) { LL | fn foo<B>(a: A) { } - | - ^ use of generic parameter from outer function + | - ^ use of generic parameter from outer item | | - | help: try using a local generic parameter instead: `A,` + | help: try introducing a local generic parameter here: `A,` error: aborting due to 4 previous errors diff --git a/tests/ui/resolve/use-self-in-inner-fn.rs b/tests/ui/resolve/use-self-in-inner-fn.rs index eccb315feb1..f4dfa4c40ab 100644 --- a/tests/ui/resolve/use-self-in-inner-fn.rs +++ b/tests/ui/resolve/use-self-in-inner-fn.rs @@ -4,9 +4,9 @@ impl A { //~^ NOTE `Self` type implicitly declared here, by this `impl` fn banana(&mut self) { fn peach(this: &Self) { - //~^ ERROR can't use generic parameters from outer function - //~| NOTE use of generic parameter from outer function - //~| NOTE use a type here instead + //~^ ERROR can't use generic parameters from outer item + //~| NOTE use of generic parameter from outer item + //~| NOTE refer to the type directly here instead } } } diff --git a/tests/ui/resolve/use-self-in-inner-fn.stderr b/tests/ui/resolve/use-self-in-inner-fn.stderr index 96609349924..832aaacaf49 100644 --- a/tests/ui/resolve/use-self-in-inner-fn.stderr +++ b/tests/ui/resolve/use-self-in-inner-fn.stderr @@ -1,4 +1,4 @@ -error[E0401]: can't use generic parameters from outer function +error[E0401]: can't use generic parameters from outer item --> $DIR/use-self-in-inner-fn.rs:6:25 | LL | impl A { @@ -7,8 +7,8 @@ LL | impl A { LL | fn peach(this: &Self) { | ^^^^ | | - | use of generic parameter from outer function - | use a type here instead + | use of generic parameter from outer item + | refer to the type directly here instead error: aborting due to previous error diff --git a/tests/ui/rfcs/rfc-2294-if-let-guard/const-expr.rs b/tests/ui/rfcs/rfc-2294-if-let-guard/const-expr.rs new file mode 100644 index 00000000000..5c42c0d8bec --- /dev/null +++ b/tests/ui/rfcs/rfc-2294-if-let-guard/const-expr.rs @@ -0,0 +1,26 @@ +// Ensure if let guards can be used in constant expressions. +// build-pass + +#![feature(if_let_guard)] + +const fn match_if_let(x: Option<i32>, y: Option<i32>) -> i32 { + match x { + None if let Some(a @ 5) = y => a, + Some(z) if let (Some(_), 12) = (y, z) => 2, + _ => 3, + } +} + +const ASSERTS: usize = { + assert!(match_if_let(None, Some(5)) == 5); + assert!(match_if_let(Some(12), Some(3)) == 2); + assert!(match_if_let(None, Some(4)) == 3); + assert!(match_if_let(Some(11), Some(3)) == 3); + assert!(match_if_let(Some(12), None) == 3); + assert!(match_if_let(None, None) == 3); + 0 +}; + +fn main() { + let _: [(); ASSERTS]; +} diff --git a/tests/ui/rfcs/rfc-2294-if-let-guard/feature-gate.rs b/tests/ui/rfcs/rfc-2294-if-let-guard/feature-gate.rs index 3beb20f0a37..b8c0eb3e6d6 100644 --- a/tests/ui/rfcs/rfc-2294-if-let-guard/feature-gate.rs +++ b/tests/ui/rfcs/rfc-2294-if-let-guard/feature-gate.rs @@ -8,14 +8,10 @@ fn _if_let_guard() { //~^ ERROR `if let` guards are experimental () if (let 0 = 1) => {} - //~^ ERROR `let` expressions in this position are unstable - //~| ERROR expected expression, found `let` statement - //~| ERROR `let` expressions are not supported here + //~^ ERROR expected expression, found `let` statement () if (((let 0 = 1))) => {} - //~^ ERROR `let` expressions in this position are unstable - //~| ERROR expected expression, found `let` statement - //~| ERROR `let` expressions are not supported here + //~^ ERROR expected expression, found `let` statement () if true && let 0 = 1 => {} //~^ ERROR `if let` guards are experimental @@ -26,36 +22,22 @@ fn _if_let_guard() { //~| ERROR `let` expressions in this position are unstable () if (let 0 = 1) && true => {} - //~^ ERROR `let` expressions in this position are unstable - //~| ERROR expected expression, found `let` statement - //~| ERROR `let` expressions are not supported here + //~^ ERROR expected expression, found `let` statement () if true && (let 0 = 1) => {} - //~^ ERROR `let` expressions in this position are unstable - //~| ERROR expected expression, found `let` statement - //~| ERROR `let` expressions are not supported here + //~^ ERROR expected expression, found `let` statement () if (let 0 = 1) && (let 0 = 1) => {} - //~^ ERROR `let` expressions in this position are unstable - //~| ERROR `let` expressions in this position are unstable + //~^ ERROR expected expression, found `let` statement //~| ERROR expected expression, found `let` statement - //~| ERROR expected expression, found `let` statement - //~| ERROR `let` expressions are not supported here - //~| ERROR `let` expressions are not supported here () if let 0 = 1 && let 1 = 2 && (let 2 = 3 && let 3 = 4 && let 4 = 5) => {} //~^ ERROR `if let` guards are experimental //~| ERROR `let` expressions in this position are unstable //~| ERROR `let` expressions in this position are unstable - //~| ERROR `let` expressions in this position are unstable - //~| ERROR `let` expressions in this position are unstable - //~| ERROR `let` expressions in this position are unstable //~| ERROR expected expression, found `let` statement //~| ERROR expected expression, found `let` statement //~| ERROR expected expression, found `let` statement - //~| ERROR `let` expressions are not supported here - //~| ERROR `let` expressions are not supported here - //~| ERROR `let` expressions are not supported here () if let Range { start: _, end: _ } = (true..true) && false => {} @@ -76,13 +58,9 @@ fn _macros() { } } use_expr!((let 0 = 1 && 0 == 0)); - //~^ ERROR `let` expressions in this position are unstable - //~| ERROR expected expression, found `let` statement - //~| ERROR `let` expressions are not supported here + //~^ ERROR expected expression, found `let` statement use_expr!((let 0 = 1)); - //~^ ERROR `let` expressions in this position are unstable - //~| ERROR expected expression, found `let` statement - //~| ERROR `let` expressions are not supported here + //~^ ERROR expected expression, found `let` statement match () { #[cfg(FALSE)] () if let 0 = 1 => {} diff --git a/tests/ui/rfcs/rfc-2294-if-let-guard/feature-gate.stderr b/tests/ui/rfcs/rfc-2294-if-let-guard/feature-gate.stderr index dc182ce464a..62534b555b2 100644 --- a/tests/ui/rfcs/rfc-2294-if-let-guard/feature-gate.stderr +++ b/tests/ui/rfcs/rfc-2294-if-let-guard/feature-gate.stderr @@ -2,87 +2,6 @@ error: expected expression, found `let` statement --> $DIR/feature-gate.rs:10:16 | LL | () if (let 0 = 1) => {} - | ^^^ - -error: expected expression, found `let` statement - --> $DIR/feature-gate.rs:15:18 - | -LL | () if (((let 0 = 1))) => {} - | ^^^ - -error: expected expression, found `let` statement - --> $DIR/feature-gate.rs:28:16 - | -LL | () if (let 0 = 1) && true => {} - | ^^^ - -error: expected expression, found `let` statement - --> $DIR/feature-gate.rs:33:24 - | -LL | () if true && (let 0 = 1) => {} - | ^^^ - -error: expected expression, found `let` statement - --> $DIR/feature-gate.rs:38:16 - | -LL | () if (let 0 = 1) && (let 0 = 1) => {} - | ^^^ - -error: expected expression, found `let` statement - --> $DIR/feature-gate.rs:38:31 - | -LL | () if (let 0 = 1) && (let 0 = 1) => {} - | ^^^ - -error: expected expression, found `let` statement - --> $DIR/feature-gate.rs:46:42 - | -LL | () if let 0 = 1 && let 1 = 2 && (let 2 = 3 && let 3 = 4 && let 4 = 5) => {} - | ^^^ - -error: expected expression, found `let` statement - --> $DIR/feature-gate.rs:46:55 - | -LL | () if let 0 = 1 && let 1 = 2 && (let 2 = 3 && let 3 = 4 && let 4 = 5) => {} - | ^^^ - -error: expected expression, found `let` statement - --> $DIR/feature-gate.rs:46:68 - | -LL | () if let 0 = 1 && let 1 = 2 && (let 2 = 3 && let 3 = 4 && let 4 = 5) => {} - | ^^^ - -error: expected expression, found `let` statement - --> $DIR/feature-gate.rs:78:16 - | -LL | use_expr!((let 0 = 1 && 0 == 0)); - | ^^^ - -error: expected expression, found `let` statement - --> $DIR/feature-gate.rs:82:16 - | -LL | use_expr!((let 0 = 1)); - | ^^^ - -error: no rules expected the token `let` - --> $DIR/feature-gate.rs:92:15 - | -LL | macro_rules! use_expr { - | --------------------- when calling this macro -... -LL | use_expr!(let 0 = 1); - | ^^^ no rules expected this token in macro call - | -note: while trying to match meta-variable `$e:expr` - --> $DIR/feature-gate.rs:71:10 - | -LL | ($e:expr) => { - | ^^^^^^^ - -error: `let` expressions are not supported here - --> $DIR/feature-gate.rs:10:16 - | -LL | () if (let 0 = 1) => {} | ^^^^^^^^^ | = note: only supported directly in conditions of `if` and `while` expressions @@ -92,135 +11,140 @@ note: `let`s wrapped in parentheses are not supported in a context with let chai LL | () if (let 0 = 1) => {} | ^^^^^^^^^ -error: `let` expressions are not supported here - --> $DIR/feature-gate.rs:15:18 +error: expected expression, found `let` statement + --> $DIR/feature-gate.rs:13:18 | LL | () if (((let 0 = 1))) => {} | ^^^^^^^^^ | = note: only supported directly in conditions of `if` and `while` expressions note: `let`s wrapped in parentheses are not supported in a context with let chains - --> $DIR/feature-gate.rs:15:18 + --> $DIR/feature-gate.rs:13:18 | LL | () if (((let 0 = 1))) => {} | ^^^^^^^^^ -error: `let` expressions are not supported here - --> $DIR/feature-gate.rs:28:16 +error: expected expression, found `let` statement + --> $DIR/feature-gate.rs:24:16 | LL | () if (let 0 = 1) && true => {} | ^^^^^^^^^ | = note: only supported directly in conditions of `if` and `while` expressions note: `let`s wrapped in parentheses are not supported in a context with let chains - --> $DIR/feature-gate.rs:28:16 + --> $DIR/feature-gate.rs:24:16 | LL | () if (let 0 = 1) && true => {} | ^^^^^^^^^ -error: `let` expressions are not supported here - --> $DIR/feature-gate.rs:33:24 +error: expected expression, found `let` statement + --> $DIR/feature-gate.rs:27:24 | LL | () if true && (let 0 = 1) => {} | ^^^^^^^^^ | = note: only supported directly in conditions of `if` and `while` expressions note: `let`s wrapped in parentheses are not supported in a context with let chains - --> $DIR/feature-gate.rs:33:24 + --> $DIR/feature-gate.rs:27:24 | LL | () if true && (let 0 = 1) => {} | ^^^^^^^^^ -error: `let` expressions are not supported here - --> $DIR/feature-gate.rs:38:16 +error: expected expression, found `let` statement + --> $DIR/feature-gate.rs:30:16 | LL | () if (let 0 = 1) && (let 0 = 1) => {} | ^^^^^^^^^ | = note: only supported directly in conditions of `if` and `while` expressions note: `let`s wrapped in parentheses are not supported in a context with let chains - --> $DIR/feature-gate.rs:38:16 + --> $DIR/feature-gate.rs:30:16 | LL | () if (let 0 = 1) && (let 0 = 1) => {} | ^^^^^^^^^ -error: `let` expressions are not supported here - --> $DIR/feature-gate.rs:38:31 +error: expected expression, found `let` statement + --> $DIR/feature-gate.rs:30:31 | LL | () if (let 0 = 1) && (let 0 = 1) => {} | ^^^^^^^^^ | = note: only supported directly in conditions of `if` and `while` expressions note: `let`s wrapped in parentheses are not supported in a context with let chains - --> $DIR/feature-gate.rs:38:31 + --> $DIR/feature-gate.rs:30:31 | LL | () if (let 0 = 1) && (let 0 = 1) => {} | ^^^^^^^^^ -error: `let` expressions are not supported here - --> $DIR/feature-gate.rs:46:42 +error: expected expression, found `let` statement + --> $DIR/feature-gate.rs:34:42 | LL | () if let 0 = 1 && let 1 = 2 && (let 2 = 3 && let 3 = 4 && let 4 = 5) => {} | ^^^^^^^^^ | = note: only supported directly in conditions of `if` and `while` expressions note: `let`s wrapped in parentheses are not supported in a context with let chains - --> $DIR/feature-gate.rs:46:42 + --> $DIR/feature-gate.rs:34:42 | LL | () if let 0 = 1 && let 1 = 2 && (let 2 = 3 && let 3 = 4 && let 4 = 5) => {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: `let` expressions are not supported here - --> $DIR/feature-gate.rs:46:55 +error: expected expression, found `let` statement + --> $DIR/feature-gate.rs:34:55 | LL | () if let 0 = 1 && let 1 = 2 && (let 2 = 3 && let 3 = 4 && let 4 = 5) => {} | ^^^^^^^^^ | = note: only supported directly in conditions of `if` and `while` expressions note: `let`s wrapped in parentheses are not supported in a context with let chains - --> $DIR/feature-gate.rs:46:42 + --> $DIR/feature-gate.rs:34:42 | LL | () if let 0 = 1 && let 1 = 2 && (let 2 = 3 && let 3 = 4 && let 4 = 5) => {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: `let` expressions are not supported here - --> $DIR/feature-gate.rs:46:68 +error: expected expression, found `let` statement + --> $DIR/feature-gate.rs:34:68 | LL | () if let 0 = 1 && let 1 = 2 && (let 2 = 3 && let 3 = 4 && let 4 = 5) => {} | ^^^^^^^^^ | = note: only supported directly in conditions of `if` and `while` expressions note: `let`s wrapped in parentheses are not supported in a context with let chains - --> $DIR/feature-gate.rs:46:42 + --> $DIR/feature-gate.rs:34:42 | LL | () if let 0 = 1 && let 1 = 2 && (let 2 = 3 && let 3 = 4 && let 4 = 5) => {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: `let` expressions are not supported here - --> $DIR/feature-gate.rs:78:16 +error: expected expression, found `let` statement + --> $DIR/feature-gate.rs:60:16 | LL | use_expr!((let 0 = 1 && 0 == 0)); - | ^^^^^^^^^ + | ^^^ | = note: only supported directly in conditions of `if` and `while` expressions -note: `let`s wrapped in parentheses are not supported in a context with let chains - --> $DIR/feature-gate.rs:78:16 - | -LL | use_expr!((let 0 = 1 && 0 == 0)); - | ^^^^^^^^^^^^^^^^^^^ -error: `let` expressions are not supported here - --> $DIR/feature-gate.rs:82:16 +error: expected expression, found `let` statement + --> $DIR/feature-gate.rs:62:16 | LL | use_expr!((let 0 = 1)); - | ^^^^^^^^^ + | ^^^ | = note: only supported directly in conditions of `if` and `while` expressions -note: `let`s wrapped in parentheses are not supported in a context with let chains - --> $DIR/feature-gate.rs:82:16 + +error: no rules expected the token `let` + --> $DIR/feature-gate.rs:70:15 | -LL | use_expr!((let 0 = 1)); - | ^^^^^^^^^ +LL | macro_rules! use_expr { + | --------------------- when calling this macro +... +LL | use_expr!(let 0 = 1); + | ^^^ no rules expected this token in macro call + | +note: while trying to match meta-variable `$e:expr` + --> $DIR/feature-gate.rs:53:10 + | +LL | ($e:expr) => { + | ^^^^^^^ error[E0658]: `if let` guards are experimental --> $DIR/feature-gate.rs:7:12 @@ -233,7 +157,7 @@ LL | () if let 0 = 1 => {} = help: you can write `if matches!(<expr>, <pattern>)` instead of `if let <pattern> = <expr>` error[E0658]: `if let` guards are experimental - --> $DIR/feature-gate.rs:20:12 + --> $DIR/feature-gate.rs:16:12 | LL | () if true && let 0 = 1 => {} | ^^^^^^^^^^^^^^^^^^^^ @@ -243,7 +167,7 @@ LL | () if true && let 0 = 1 => {} = help: you can write `if matches!(<expr>, <pattern>)` instead of `if let <pattern> = <expr>` error[E0658]: `if let` guards are experimental - --> $DIR/feature-gate.rs:24:12 + --> $DIR/feature-gate.rs:20:12 | LL | () if let 0 = 1 && true => {} | ^^^^^^^^^^^^^^^^^^^^ @@ -253,7 +177,7 @@ LL | () if let 0 = 1 && true => {} = help: you can write `if matches!(<expr>, <pattern>)` instead of `if let <pattern> = <expr>` error[E0658]: `if let` guards are experimental - --> $DIR/feature-gate.rs:46:12 + --> $DIR/feature-gate.rs:34:12 | LL | () if let 0 = 1 && let 1 = 2 && (let 2 = 3 && let 3 = 4 && let 4 = 5) => {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -263,7 +187,7 @@ LL | () if let 0 = 1 && let 1 = 2 && (let 2 = 3 && let 3 = 4 && let 4 = = help: you can write `if matches!(<expr>, <pattern>)` instead of `if let <pattern> = <expr>` error[E0658]: `if let` guards are experimental - --> $DIR/feature-gate.rs:61:12 + --> $DIR/feature-gate.rs:43:12 | LL | () if let Range { start: _, end: _ } = (true..true) && false => {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -273,7 +197,7 @@ LL | () if let Range { start: _, end: _ } = (true..true) && false => {} = help: you can write `if matches!(<expr>, <pattern>)` instead of `if let <pattern> = <expr>` error[E0658]: `if let` guards are experimental - --> $DIR/feature-gate.rs:88:12 + --> $DIR/feature-gate.rs:66:12 | LL | () if let 0 = 1 => {} | ^^^^^^^^^^^^ @@ -283,25 +207,7 @@ LL | () if let 0 = 1 => {} = help: you can write `if matches!(<expr>, <pattern>)` instead of `if let <pattern> = <expr>` error[E0658]: `let` expressions in this position are unstable - --> $DIR/feature-gate.rs:10:16 - | -LL | () if (let 0 = 1) => {} - | ^^^^^^^^^ - | - = note: see issue #53667 <https://github.com/rust-lang/rust/issues/53667> for more information - = help: add `#![feature(let_chains)]` to the crate attributes to enable - -error[E0658]: `let` expressions in this position are unstable - --> $DIR/feature-gate.rs:15:18 - | -LL | () if (((let 0 = 1))) => {} - | ^^^^^^^^^ - | - = note: see issue #53667 <https://github.com/rust-lang/rust/issues/53667> for more information - = help: add `#![feature(let_chains)]` to the crate attributes to enable - -error[E0658]: `let` expressions in this position are unstable - --> $DIR/feature-gate.rs:20:23 + --> $DIR/feature-gate.rs:16:23 | LL | () if true && let 0 = 1 => {} | ^^^^^^^^^ @@ -310,7 +216,7 @@ LL | () if true && let 0 = 1 => {} = help: add `#![feature(let_chains)]` to the crate attributes to enable error[E0658]: `let` expressions in this position are unstable - --> $DIR/feature-gate.rs:24:15 + --> $DIR/feature-gate.rs:20:15 | LL | () if let 0 = 1 && true => {} | ^^^^^^^^^ @@ -319,43 +225,7 @@ LL | () if let 0 = 1 && true => {} = help: add `#![feature(let_chains)]` to the crate attributes to enable error[E0658]: `let` expressions in this position are unstable - --> $DIR/feature-gate.rs:28:16 - | -LL | () if (let 0 = 1) && true => {} - | ^^^^^^^^^ - | - = note: see issue #53667 <https://github.com/rust-lang/rust/issues/53667> for more information - = help: add `#![feature(let_chains)]` to the crate attributes to enable - -error[E0658]: `let` expressions in this position are unstable - --> $DIR/feature-gate.rs:33:24 - | -LL | () if true && (let 0 = 1) => {} - | ^^^^^^^^^ - | - = note: see issue #53667 <https://github.com/rust-lang/rust/issues/53667> for more information - = help: add `#![feature(let_chains)]` to the crate attributes to enable - -error[E0658]: `let` expressions in this position are unstable - --> $DIR/feature-gate.rs:38:16 - | -LL | () if (let 0 = 1) && (let 0 = 1) => {} - | ^^^^^^^^^ - | - = note: see issue #53667 <https://github.com/rust-lang/rust/issues/53667> for more information - = help: add `#![feature(let_chains)]` to the crate attributes to enable - -error[E0658]: `let` expressions in this position are unstable - --> $DIR/feature-gate.rs:38:31 - | -LL | () if (let 0 = 1) && (let 0 = 1) => {} - | ^^^^^^^^^ - | - = note: see issue #53667 <https://github.com/rust-lang/rust/issues/53667> for more information - = help: add `#![feature(let_chains)]` to the crate attributes to enable - -error[E0658]: `let` expressions in this position are unstable - --> $DIR/feature-gate.rs:46:15 + --> $DIR/feature-gate.rs:34:15 | LL | () if let 0 = 1 && let 1 = 2 && (let 2 = 3 && let 3 = 4 && let 4 = 5) => {} | ^^^^^^^^^ @@ -364,7 +234,7 @@ LL | () if let 0 = 1 && let 1 = 2 && (let 2 = 3 && let 3 = 4 && let 4 = = help: add `#![feature(let_chains)]` to the crate attributes to enable error[E0658]: `let` expressions in this position are unstable - --> $DIR/feature-gate.rs:46:28 + --> $DIR/feature-gate.rs:34:28 | LL | () if let 0 = 1 && let 1 = 2 && (let 2 = 3 && let 3 = 4 && let 4 = 5) => {} | ^^^^^^^^^ @@ -373,34 +243,7 @@ LL | () if let 0 = 1 && let 1 = 2 && (let 2 = 3 && let 3 = 4 && let 4 = = help: add `#![feature(let_chains)]` to the crate attributes to enable error[E0658]: `let` expressions in this position are unstable - --> $DIR/feature-gate.rs:46:42 - | -LL | () if let 0 = 1 && let 1 = 2 && (let 2 = 3 && let 3 = 4 && let 4 = 5) => {} - | ^^^^^^^^^ - | - = note: see issue #53667 <https://github.com/rust-lang/rust/issues/53667> for more information - = help: add `#![feature(let_chains)]` to the crate attributes to enable - -error[E0658]: `let` expressions in this position are unstable - --> $DIR/feature-gate.rs:46:55 - | -LL | () if let 0 = 1 && let 1 = 2 && (let 2 = 3 && let 3 = 4 && let 4 = 5) => {} - | ^^^^^^^^^ - | - = note: see issue #53667 <https://github.com/rust-lang/rust/issues/53667> for more information - = help: add `#![feature(let_chains)]` to the crate attributes to enable - -error[E0658]: `let` expressions in this position are unstable - --> $DIR/feature-gate.rs:46:68 - | -LL | () if let 0 = 1 && let 1 = 2 && (let 2 = 3 && let 3 = 4 && let 4 = 5) => {} - | ^^^^^^^^^ - | - = note: see issue #53667 <https://github.com/rust-lang/rust/issues/53667> for more information - = help: add `#![feature(let_chains)]` to the crate attributes to enable - -error[E0658]: `let` expressions in this position are unstable - --> $DIR/feature-gate.rs:61:15 + --> $DIR/feature-gate.rs:43:15 | LL | () if let Range { start: _, end: _ } = (true..true) && false => {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -408,24 +251,6 @@ LL | () if let Range { start: _, end: _ } = (true..true) && false => {} = note: see issue #53667 <https://github.com/rust-lang/rust/issues/53667> for more information = help: add `#![feature(let_chains)]` to the crate attributes to enable -error[E0658]: `let` expressions in this position are unstable - --> $DIR/feature-gate.rs:78:16 - | -LL | use_expr!((let 0 = 1 && 0 == 0)); - | ^^^^^^^^^ - | - = note: see issue #53667 <https://github.com/rust-lang/rust/issues/53667> for more information - = help: add `#![feature(let_chains)]` to the crate attributes to enable - -error[E0658]: `let` expressions in this position are unstable - --> $DIR/feature-gate.rs:82:16 - | -LL | use_expr!((let 0 = 1)); - | ^^^^^^^^^ - | - = note: see issue #53667 <https://github.com/rust-lang/rust/issues/53667> for more information - = help: add `#![feature(let_chains)]` to the crate attributes to enable - -error: aborting due to 45 previous errors +error: aborting due to 23 previous errors For more information about this error, try `rustc --explain E0658`. diff --git a/tests/ui/rfcs/rfc-2294-if-let-guard/macro-expanded.stderr b/tests/ui/rfcs/rfc-2294-if-let-guard/macro-expanded.stderr index 41a20bf8ae1..00c1c303d2b 100644 --- a/tests/ui/rfcs/rfc-2294-if-let-guard/macro-expanded.stderr +++ b/tests/ui/rfcs/rfc-2294-if-let-guard/macro-expanded.stderr @@ -7,6 +7,7 @@ LL | ($e:expr) => { let Some(x) = $e } LL | () if m!(Some(5)) => {} | ----------- in this macro invocation | + = note: only supported directly in conditions of `if` and `while` expressions = note: this error originates in the macro `m` (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to previous error diff --git a/tests/ui/rfcs/rfc-2294-if-let-guard/move-guard-if-let-chain.rs b/tests/ui/rfcs/rfc-2294-if-let-guard/move-guard-if-let-chain.rs new file mode 100644 index 00000000000..5c333cd7795 --- /dev/null +++ b/tests/ui/rfcs/rfc-2294-if-let-guard/move-guard-if-let-chain.rs @@ -0,0 +1,97 @@ +#![feature(if_let_guard)] +#![feature(let_chains)] +#![allow(irrefutable_let_patterns)] + +fn same_pattern(c: bool) { + let x: Box<_> = Box::new(1); + + let v = (1, 2); + + match v { + (1, 2) if let y = x && c => (), + (1, 2) if let z = x => (), //~ ERROR use of moved value: `x` + _ => (), + } +} + +fn same_pattern_ok(c: bool) { + let x: Box<_> = Box::new(1); + + let v = (1, 2); + + match v { + (1, 2) if c && let y = x => (), + (1, 2) if let z = x => (), + _ => (), + } +} + +fn different_patterns(c: bool) { + let x: Box<_> = Box::new(1); + + let v = (1, 2); + + match v { + (1, _) if let y = x && c => (), + (_, 2) if let z = x => (), //~ ERROR use of moved value: `x` + _ => (), + } +} + +fn different_patterns_ok(c: bool) { + let x: Box<_> = Box::new(1); + + let v = (1, 2); + + match v { + (1, _) if c && let y = x => (), + (_, 2) if let z = x => (), + _ => (), + } +} + +fn or_pattern(c: bool) { + let x: Box<_> = Box::new(1); + + let v = (1, 2); + + match v { + (1, _) | (_, 2) if let y = x && c => (), //~ ERROR use of moved value: `x` + _ => (), + } +} + +fn or_pattern_ok(c: bool) { + let x: Box<_> = Box::new(1); + + let v = (1, 2); + + match v { + (1, _) | (_, 2) if c && let y = x => (), + _ => (), + } +} + +fn use_in_arm(c: bool) { + let x: Box<_> = Box::new(1); + + let v = (1, 2); + + match v { + (1, 2) if let y = x && c => false, + _ => { *x == 1 }, //~ ERROR use of moved value: `x` + }; +} + +fn use_in_arm_ok(c: bool) { + let x: Box<_> = Box::new(1); + + let v = (1, 2); + + match v { + (1, 2) if c && let y = x => false, + _ => { *x == 1 }, + }; +} + +fn main() {} diff --git a/tests/ui/rfcs/rfc-2294-if-let-guard/move-guard-if-let-chain.stderr b/tests/ui/rfcs/rfc-2294-if-let-guard/move-guard-if-let-chain.stderr new file mode 100644 index 00000000000..d27fde58244 --- /dev/null +++ b/tests/ui/rfcs/rfc-2294-if-let-guard/move-guard-if-let-chain.stderr @@ -0,0 +1,67 @@ +error[E0382]: use of moved value: `x` + --> $DIR/move-guard-if-let-chain.rs:12:27 + | +LL | let x: Box<_> = Box::new(1); + | - move occurs because `x` has type `Box<i32>`, which does not implement the `Copy` trait +... +LL | (1, 2) if let y = x && c => (), + | - value moved here +LL | (1, 2) if let z = x => (), + | ^ value used here after move + | +help: borrow this binding in the pattern to avoid moving the value + | +LL | (1, 2) if let ref y = x && c => (), + | +++ + +error[E0382]: use of moved value: `x` + --> $DIR/move-guard-if-let-chain.rs:36:27 + | +LL | let x: Box<_> = Box::new(1); + | - move occurs because `x` has type `Box<i32>`, which does not implement the `Copy` trait +... +LL | (1, _) if let y = x && c => (), + | - value moved here +LL | (_, 2) if let z = x => (), + | ^ value used here after move + | +help: borrow this binding in the pattern to avoid moving the value + | +LL | (1, _) if let ref y = x && c => (), + | +++ + +error[E0382]: use of moved value: `x` + --> $DIR/move-guard-if-let-chain.rs:59:36 + | +LL | let x: Box<_> = Box::new(1); + | - move occurs because `x` has type `Box<i32>`, which does not implement the `Copy` trait +... +LL | (1, _) | (_, 2) if let y = x && c => (), + | - ^ value used here after move + | | + | value moved here + | +help: borrow this binding in the pattern to avoid moving the value + | +LL | (1, _) | (_, 2) if let ref y = x && c => (), + | +++ + +error[E0382]: use of moved value: `x` + --> $DIR/move-guard-if-let-chain.rs:82:16 + | +LL | let x: Box<_> = Box::new(1); + | - move occurs because `x` has type `Box<i32>`, which does not implement the `Copy` trait +... +LL | (1, 2) if let y = x && c => false, + | - value moved here +LL | _ => { *x == 1 }, + | ^^ value used here after move + | +help: borrow this binding in the pattern to avoid moving the value + | +LL | (1, 2) if let ref y = x && c => false, + | +++ + +error: aborting due to 4 previous errors + +For more information about this error, try `rustc --explain E0382`. diff --git a/tests/ui/rfcs/rfc-2294-if-let-guard/move-guard-if-let.rs b/tests/ui/rfcs/rfc-2294-if-let-guard/move-guard-if-let.rs new file mode 100644 index 00000000000..071b86e2e14 --- /dev/null +++ b/tests/ui/rfcs/rfc-2294-if-let-guard/move-guard-if-let.rs @@ -0,0 +1,41 @@ +// Check that borrowck knows that moves in the pattern for if-let guards +// only happen when the pattern is matched. + +// build-pass + +#![feature(if_let_guard)] +#![allow(irrefutable_let_patterns)] + +fn same_pattern() { + let x: Box<_> = Box::new(1); + + let v = (1, 2); + + match v { + (1, 2) if let y = x => (), + (1, 2) if let z = x => (), + _ => (), + } +} + +fn or_pattern() { + let x: Box<_> = Box::new(1); + + let v = (1, 2); + + match v { + (1, _) | (_, 2) if let y = x => (), + _ => (), + } +} + +fn main() { + let x: Box<_> = Box::new(1); + + let v = (1, 2); + + match v { + (1, 2) if let y = x => false, + _ => { *x == 1 }, + }; +} diff --git a/tests/ui/rfcs/rfc-2294-if-let-guard/parens.rs b/tests/ui/rfcs/rfc-2294-if-let-guard/parens.rs index 9cb27c73b14..f12824db9c0 100644 --- a/tests/ui/rfcs/rfc-2294-if-let-guard/parens.rs +++ b/tests/ui/rfcs/rfc-2294-if-let-guard/parens.rs @@ -19,9 +19,7 @@ fn main() { () if let 0 = 1 => {} () if (let 0 = 1) => {} //~^ ERROR expected expression, found `let` statement - //~| ERROR `let` expressions are not supported here () if (((let 0 = 1))) => {} //~^ ERROR expected expression, found `let` statement - //~| ERROR `let` expressions are not supported here } } diff --git a/tests/ui/rfcs/rfc-2294-if-let-guard/parens.stderr b/tests/ui/rfcs/rfc-2294-if-let-guard/parens.stderr index 85df360daab..0c16d9c5442 100644 --- a/tests/ui/rfcs/rfc-2294-if-let-guard/parens.stderr +++ b/tests/ui/rfcs/rfc-2294-if-let-guard/parens.stderr @@ -2,27 +2,29 @@ error: expected expression, found `let` statement --> $DIR/parens.rs:10:16 | LL | () if (let 0 = 1) => {} - | ^^^ + | ^^^^^^^^^ + | + = note: only supported directly in conditions of `if` and `while` expressions +note: `let`s wrapped in parentheses are not supported in a context with let chains + --> $DIR/parens.rs:10:16 + | +LL | () if (let 0 = 1) => {} + | ^^^^^^^^^ error: expected expression, found `let` statement --> $DIR/parens.rs:12:18 | LL | () if (((let 0 = 1))) => {} - | ^^^ - -error: expected expression, found `let` statement - --> $DIR/parens.rs:20:16 + | ^^^^^^^^^ | -LL | () if (let 0 = 1) => {} - | ^^^ - -error: expected expression, found `let` statement - --> $DIR/parens.rs:23:18 + = note: only supported directly in conditions of `if` and `while` expressions +note: `let`s wrapped in parentheses are not supported in a context with let chains + --> $DIR/parens.rs:12:18 | LL | () if (((let 0 = 1))) => {} - | ^^^ + | ^^^^^^^^^ -error: `let` expressions are not supported here +error: expected expression, found `let` statement --> $DIR/parens.rs:20:16 | LL | () if (let 0 = 1) => {} @@ -35,18 +37,18 @@ note: `let`s wrapped in parentheses are not supported in a context with let chai LL | () if (let 0 = 1) => {} | ^^^^^^^^^ -error: `let` expressions are not supported here - --> $DIR/parens.rs:23:18 +error: expected expression, found `let` statement + --> $DIR/parens.rs:22:18 | LL | () if (((let 0 = 1))) => {} | ^^^^^^^^^ | = note: only supported directly in conditions of `if` and `while` expressions note: `let`s wrapped in parentheses are not supported in a context with let chains - --> $DIR/parens.rs:23:18 + --> $DIR/parens.rs:22:18 | LL | () if (((let 0 = 1))) => {} | ^^^^^^^^^ -error: aborting due to 6 previous errors +error: aborting due to 4 previous errors diff --git a/tests/ui/rfcs/rfc-2294-if-let-guard/type-inference.rs b/tests/ui/rfcs/rfc-2294-if-let-guard/type-inference.rs new file mode 100644 index 00000000000..ef7a772e6c5 --- /dev/null +++ b/tests/ui/rfcs/rfc-2294-if-let-guard/type-inference.rs @@ -0,0 +1,16 @@ +// check-pass + +#![feature(if_let_guard)] + +struct S; + +fn get<T>() -> Option<T> { + None +} + +fn main() { + match get() { + x if let Some(S) = x => {} + _ => {} + } +} diff --git a/tests/ui/rfcs/rfc-2497-if-let-chains/ast-validate-guards.rs b/tests/ui/rfcs/rfc-2497-if-let-chains/ast-validate-guards.rs index e6dee2a1d06..cb3be59bee0 100644 --- a/tests/ui/rfcs/rfc-2497-if-let-chains/ast-validate-guards.rs +++ b/tests/ui/rfcs/rfc-2497-if-let-chains/ast-validate-guards.rs @@ -3,7 +3,7 @@ fn let_or_guard(x: Result<Option<i32>, ()>) { match x { Ok(opt) if let Some(4) = opt || false => {} - //~^ ERROR `let` expressions are not supported here + //~^ ERROR expected expression, found `let` statement _ => {} } } diff --git a/tests/ui/rfcs/rfc-2497-if-let-chains/ast-validate-guards.stderr b/tests/ui/rfcs/rfc-2497-if-let-chains/ast-validate-guards.stderr index 26850998cc4..4b85fdd5050 100644 --- a/tests/ui/rfcs/rfc-2497-if-let-chains/ast-validate-guards.stderr +++ b/tests/ui/rfcs/rfc-2497-if-let-chains/ast-validate-guards.stderr @@ -1,4 +1,4 @@ -error: `let` expressions are not supported here +error: expected expression, found `let` statement --> $DIR/ast-validate-guards.rs:5:20 | LL | Ok(opt) if let Some(4) = opt || false => {} diff --git a/tests/ui/rfcs/rfc-2497-if-let-chains/avoid-invalid-mir.rs b/tests/ui/rfcs/rfc-2497-if-let-chains/avoid-invalid-mir.rs new file mode 100644 index 00000000000..530458064b2 --- /dev/null +++ b/tests/ui/rfcs/rfc-2497-if-let-chains/avoid-invalid-mir.rs @@ -0,0 +1,14 @@ +// Regression test for #104172 + +const N: usize = { + struct U; + !let y = 42; + //~^ ERROR expected expression, found `let` statement + 3 +}; + +struct S { + x: [(); N] +} + +fn main() {} diff --git a/tests/ui/rfcs/rfc-2497-if-let-chains/avoid-invalid-mir.stderr b/tests/ui/rfcs/rfc-2497-if-let-chains/avoid-invalid-mir.stderr new file mode 100644 index 00000000000..3eaccde3b74 --- /dev/null +++ b/tests/ui/rfcs/rfc-2497-if-let-chains/avoid-invalid-mir.stderr @@ -0,0 +1,10 @@ +error: expected expression, found `let` statement + --> $DIR/avoid-invalid-mir.rs:5:6 + | +LL | !let y = 42; + | ^^^ + | + = note: only supported directly in conditions of `if` and `while` expressions + +error: aborting due to previous error + diff --git a/tests/ui/rfcs/rfc-2497-if-let-chains/disallowed-positions-without-feature-gate.rs b/tests/ui/rfcs/rfc-2497-if-let-chains/disallowed-positions-without-feature-gate.rs new file mode 100644 index 00000000000..096036bb133 --- /dev/null +++ b/tests/ui/rfcs/rfc-2497-if-let-chains/disallowed-positions-without-feature-gate.rs @@ -0,0 +1,340 @@ +// Check that we don't suggest enabling a feature for code that's +// not accepted even with that feature. + +#![allow(irrefutable_let_patterns)] + +use std::ops::Range; + +fn main() {} + +fn _if() { + if (let 0 = 1) {} + //~^ ERROR expected expression, found `let` statement + + if (((let 0 = 1))) {} + //~^ ERROR expected expression, found `let` statement + + if (let 0 = 1) && true {} + //~^ ERROR expected expression, found `let` statement + + if true && (let 0 = 1) {} + //~^ ERROR expected expression, found `let` statement + + if (let 0 = 1) && (let 0 = 1) {} + //~^ ERROR expected expression, found `let` statement + //~| ERROR expected expression, found `let` statement + + if (let 2 = 3 && let 3 = 4 && let 4 = 5) {} + //~^ ERROR expected expression, found `let` statement + //~| ERROR expected expression, found `let` statement + //~| ERROR expected expression, found `let` statement +} + +fn _while() { + while (let 0 = 1) {} + //~^ ERROR expected expression, found `let` statement + + while (((let 0 = 1))) {} + //~^ ERROR expected expression, found `let` statement + + while (let 0 = 1) && true {} + //~^ ERROR expected expression, found `let` statement + + while true && (let 0 = 1) {} + //~^ ERROR expected expression, found `let` statement + + while (let 0 = 1) && (let 0 = 1) {} + //~^ ERROR expected expression, found `let` statement + //~| ERROR expected expression, found `let` statement + + while (let 2 = 3 && let 3 = 4 && let 4 = 5) {} + //~^ ERROR expected expression, found `let` statement + //~| ERROR expected expression, found `let` statement + //~| ERROR expected expression, found `let` statement +} + +fn _macros() { + macro_rules! use_expr { + ($e:expr) => { + if $e {} + while $e {} + } + } + use_expr!((let 0 = 1 && 0 == 0)); + //~^ ERROR expected expression, found `let` statement + use_expr!((let 0 = 1)); + //~^ ERROR expected expression, found `let` statement +} + +fn nested_within_if_expr() { + if &let 0 = 0 {} + //~^ ERROR expected expression, found `let` statement + + if !let 0 = 0 {} + //~^ ERROR expected expression, found `let` statement + if *let 0 = 0 {} + //~^ ERROR expected expression, found `let` statement + if -let 0 = 0 {} + //~^ ERROR expected expression, found `let` statement + + fn _check_try_binds_tighter() -> Result<(), ()> { + if let 0 = 0? {} + //~^ ERROR the `?` operator can only be applied to values that implement `Try` + Ok(()) + } + if (let 0 = 0)? {} + //~^ ERROR expected expression, found `let` statement + + if true || let 0 = 0 {} + //~^ ERROR expected expression, found `let` statement + if (true || let 0 = 0) {} + //~^ ERROR expected expression, found `let` statement + if true && (true || let 0 = 0) {} + //~^ ERROR expected expression, found `let` statement + if true || (true && let 0 = 0) {} + //~^ ERROR expected expression, found `let` statement + + let mut x = true; + if x = let 0 = 0 {} + //~^ ERROR expected expression, found `let` statement + + if true..(let 0 = 0) {} + //~^ ERROR expected expression, found `let` statement + //~| ERROR mismatched types + if ..(let 0 = 0) {} + //~^ ERROR expected expression, found `let` statement + if (let 0 = 0).. {} + //~^ ERROR expected expression, found `let` statement + + // Binds as `(let ... = true)..true &&/|| false`. + if let Range { start: _, end: _ } = true..true && false {} + //~^ ERROR expected expression, found `let` statement + //~| ERROR mismatched types + if let Range { start: _, end: _ } = true..true || false {} + //~^ ERROR expected expression, found `let` statement + //~| ERROR mismatched types + + // Binds as `(let Range { start: F, end } = F)..(|| true)`. + const F: fn() -> bool = || true; + if let Range { start: F, end } = F..|| true {} + //~^ ERROR expected expression, found `let` statement + //~| ERROR mismatched types + + // Binds as `(let Range { start: true, end } = t)..(&&false)`. + let t = &&true; + if let Range { start: true, end } = t..&&false {} + //~^ ERROR expected expression, found `let` statement + //~| ERROR mismatched types + + if let true = let true = true {} + //~^ ERROR expected expression, found `let` statement +} + +fn nested_within_while_expr() { + while &let 0 = 0 {} + //~^ ERROR expected expression, found `let` statement + + while !let 0 = 0 {} + //~^ ERROR expected expression, found `let` statement + while *let 0 = 0 {} + //~^ ERROR expected expression, found `let` statement + while -let 0 = 0 {} + //~^ ERROR expected expression, found `let` statement + + fn _check_try_binds_tighter() -> Result<(), ()> { + while let 0 = 0? {} + //~^ ERROR the `?` operator can only be applied to values that implement `Try` + Ok(()) + } + while (let 0 = 0)? {} + //~^ ERROR expected expression, found `let` statement + + while true || let 0 = 0 {} + //~^ ERROR expected expression, found `let` statement + while (true || let 0 = 0) {} + //~^ ERROR expected expression, found `let` statement + while true && (true || let 0 = 0) {} + //~^ ERROR expected expression, found `let` statement + while true || (true && let 0 = 0) {} + //~^ ERROR expected expression, found `let` statement + + let mut x = true; + while x = let 0 = 0 {} + //~^ ERROR expected expression, found `let` statement + + while true..(let 0 = 0) {} + //~^ ERROR expected expression, found `let` statement + //~| ERROR mismatched types + while ..(let 0 = 0) {} + //~^ ERROR expected expression, found `let` statement + while (let 0 = 0).. {} + //~^ ERROR expected expression, found `let` statement + + // Binds as `(let ... = true)..true &&/|| false`. + while let Range { start: _, end: _ } = true..true && false {} + //~^ ERROR expected expression, found `let` statement + //~| ERROR mismatched types + while let Range { start: _, end: _ } = true..true || false {} + //~^ ERROR expected expression, found `let` statement + //~| ERROR mismatched types + + // Binds as `(let Range { start: F, end } = F)..(|| true)`. + const F: fn() -> bool = || true; + while let Range { start: F, end } = F..|| true {} + //~^ ERROR expected expression, found `let` statement + //~| ERROR mismatched types + + // Binds as `(let Range { start: true, end } = t)..(&&false)`. + let t = &&true; + while let Range { start: true, end } = t..&&false {} + //~^ ERROR expected expression, found `let` statement + //~| ERROR mismatched types + + while let true = let true = true {} + //~^ ERROR expected expression, found `let` statement +} + +fn not_error_because_clarified_intent() { + if let Range { start: _, end: _ } = (true..true || false) { } + + if let Range { start: _, end: _ } = (true..true && false) { } + + while let Range { start: _, end: _ } = (true..true || false) { } + + while let Range { start: _, end: _ } = (true..true && false) { } +} + +fn outside_if_and_while_expr() { + &let 0 = 0; + //~^ ERROR expected expression, found `let` statement + + !let 0 = 0; + //~^ ERROR expected expression, found `let` statement + *let 0 = 0; + //~^ ERROR expected expression, found `let` statement + -let 0 = 0; + //~^ ERROR expected expression, found `let` statement + let _ = let _ = 3; + //~^ ERROR expected expression, found `let` statement + + fn _check_try_binds_tighter() -> Result<(), ()> { + let 0 = 0?; + //~^ ERROR the `?` operator can only be applied to values that implement `Try` + Ok(()) + } + (let 0 = 0)?; + //~^ ERROR expected expression, found `let` statement + + true || let 0 = 0; + //~^ ERROR expected expression, found `let` statement + (true || let 0 = 0); + //~^ ERROR expected expression, found `let` statement + true && (true || let 0 = 0); + //~^ ERROR expected expression, found `let` statement + + let mut x = true; + x = let 0 = 0; + //~^ ERROR expected expression, found `let` statement + + true..(let 0 = 0); + //~^ ERROR expected expression, found `let` statement + ..(let 0 = 0); + //~^ ERROR expected expression, found `let` statement + (let 0 = 0)..; + //~^ ERROR expected expression, found `let` statement + + (let Range { start: _, end: _ } = true..true || false); + //~^ ERROR mismatched types + //~| ERROR expected expression, found `let` statement + + (let true = let true = true); + //~^ ERROR expected expression, found `let` statement + //~| ERROR expected expression, found `let` statement + + { + #[cfg(FALSE)] + let x = true && let y = 1; + //~^ ERROR expected expression, found `let` statement + } + + #[cfg(FALSE)] + { + [1, 2, 3][let _ = ()] + //~^ ERROR expected expression, found `let` statement + } + + // Check function tail position. + &let 0 = 0 + //~^ ERROR expected expression, found `let` statement +} + +// Let's make sure that `let` inside const generic arguments are considered. +fn inside_const_generic_arguments() { + struct A<const B: bool>; + impl<const B: bool> A<{B}> { const O: u32 = 5; } + + if let A::<{ + true && let 1 = 1 + //~^ ERROR expected expression, found `let` statement + }>::O = 5 {} + + while let A::<{ + true && let 1 = 1 + //~^ ERROR expected expression, found `let` statement + }>::O = 5 {} + + if A::<{ + true && let 1 = 1 + //~^ ERROR expected expression, found `let` statement + }>::O == 5 {} + + // In the cases above we have `ExprKind::Block` to help us out. + // Below however, we would not have a block and so an implementation might go + // from visiting expressions to types without banning `let` expressions down the tree. + // This tests ensures that we are not caught by surprise should the parser + // admit non-IDENT expressions in const generic arguments. + + if A::< + true && let 1 = 1 + //~^ ERROR expressions must be enclosed in braces + //~| ERROR expected expression, found `let` statement + >::O == 5 {} +} + +fn with_parenthesis() { + let opt = Some(Some(1i32)); + + if (let Some(a) = opt && true) { + //~^ ERROR expected expression, found `let` statement + } + + if (let Some(a) = opt) && true { + //~^ ERROR expected expression, found `let` statement + } + if (let Some(a) = opt) && (let Some(b) = a) { + //~^ ERROR expected expression, found `let` statement + //~| ERROR expected expression, found `let` statement + } + + if (let Some(a) = opt && (let Some(b) = a)) && b == 1 { + //~^ ERROR expected expression, found `let` statement + //~| ERROR expected expression, found `let` statement + } + if (let Some(a) = opt && (let Some(b) = a)) && true { + //~^ ERROR expected expression, found `let` statement + //~| ERROR expected expression, found `let` statement + } + if (let Some(a) = opt && (true)) && true { + //~^ ERROR expected expression, found `let` statement + } + + #[cfg(FALSE)] + let x = (true && let y = 1); + //~^ ERROR expected expression, found `let` statement + + #[cfg(FALSE)] + { + ([1, 2, 3][let _ = ()]) + //~^ ERROR expected expression, found `let` statement + } +} diff --git a/tests/ui/rfcs/rfc-2497-if-let-chains/disallowed-positions-without-feature-gate.stderr b/tests/ui/rfcs/rfc-2497-if-let-chains/disallowed-positions-without-feature-gate.stderr new file mode 100644 index 00000000000..31f389512ed --- /dev/null +++ b/tests/ui/rfcs/rfc-2497-if-let-chains/disallowed-positions-without-feature-gate.stderr @@ -0,0 +1,1021 @@ +error: expected expression, found `let` statement + --> $DIR/disallowed-positions-without-feature-gate.rs:11:9 + | +LL | if (let 0 = 1) {} + | ^^^^^^^^^ + | + = note: only supported directly in conditions of `if` and `while` expressions +note: `let`s wrapped in parentheses are not supported in a context with let chains + --> $DIR/disallowed-positions-without-feature-gate.rs:11:9 + | +LL | if (let 0 = 1) {} + | ^^^^^^^^^ + +error: expected expression, found `let` statement + --> $DIR/disallowed-positions-without-feature-gate.rs:14:11 + | +LL | if (((let 0 = 1))) {} + | ^^^^^^^^^ + | + = note: only supported directly in conditions of `if` and `while` expressions +note: `let`s wrapped in parentheses are not supported in a context with let chains + --> $DIR/disallowed-positions-without-feature-gate.rs:14:11 + | +LL | if (((let 0 = 1))) {} + | ^^^^^^^^^ + +error: expected expression, found `let` statement + --> $DIR/disallowed-positions-without-feature-gate.rs:17:9 + | +LL | if (let 0 = 1) && true {} + | ^^^^^^^^^ + | + = note: only supported directly in conditions of `if` and `while` expressions +note: `let`s wrapped in parentheses are not supported in a context with let chains + --> $DIR/disallowed-positions-without-feature-gate.rs:17:9 + | +LL | if (let 0 = 1) && true {} + | ^^^^^^^^^ + +error: expected expression, found `let` statement + --> $DIR/disallowed-positions-without-feature-gate.rs:20:17 + | +LL | if true && (let 0 = 1) {} + | ^^^^^^^^^ + | + = note: only supported directly in conditions of `if` and `while` expressions +note: `let`s wrapped in parentheses are not supported in a context with let chains + --> $DIR/disallowed-positions-without-feature-gate.rs:20:17 + | +LL | if true && (let 0 = 1) {} + | ^^^^^^^^^ + +error: expected expression, found `let` statement + --> $DIR/disallowed-positions-without-feature-gate.rs:23:9 + | +LL | if (let 0 = 1) && (let 0 = 1) {} + | ^^^^^^^^^ + | + = note: only supported directly in conditions of `if` and `while` expressions +note: `let`s wrapped in parentheses are not supported in a context with let chains + --> $DIR/disallowed-positions-without-feature-gate.rs:23:9 + | +LL | if (let 0 = 1) && (let 0 = 1) {} + | ^^^^^^^^^ + +error: expected expression, found `let` statement + --> $DIR/disallowed-positions-without-feature-gate.rs:23:24 + | +LL | if (let 0 = 1) && (let 0 = 1) {} + | ^^^^^^^^^ + | + = note: only supported directly in conditions of `if` and `while` expressions +note: `let`s wrapped in parentheses are not supported in a context with let chains + --> $DIR/disallowed-positions-without-feature-gate.rs:23:24 + | +LL | if (let 0 = 1) && (let 0 = 1) {} + | ^^^^^^^^^ + +error: expected expression, found `let` statement + --> $DIR/disallowed-positions-without-feature-gate.rs:27:9 + | +LL | if (let 2 = 3 && let 3 = 4 && let 4 = 5) {} + | ^^^^^^^^^ + | + = note: only supported directly in conditions of `if` and `while` expressions +note: `let`s wrapped in parentheses are not supported in a context with let chains + --> $DIR/disallowed-positions-without-feature-gate.rs:27:9 + | +LL | if (let 2 = 3 && let 3 = 4 && let 4 = 5) {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: expected expression, found `let` statement + --> $DIR/disallowed-positions-without-feature-gate.rs:27:22 + | +LL | if (let 2 = 3 && let 3 = 4 && let 4 = 5) {} + | ^^^^^^^^^ + | + = note: only supported directly in conditions of `if` and `while` expressions +note: `let`s wrapped in parentheses are not supported in a context with let chains + --> $DIR/disallowed-positions-without-feature-gate.rs:27:9 + | +LL | if (let 2 = 3 && let 3 = 4 && let 4 = 5) {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: expected expression, found `let` statement + --> $DIR/disallowed-positions-without-feature-gate.rs:27:35 + | +LL | if (let 2 = 3 && let 3 = 4 && let 4 = 5) {} + | ^^^^^^^^^ + | + = note: only supported directly in conditions of `if` and `while` expressions +note: `let`s wrapped in parentheses are not supported in a context with let chains + --> $DIR/disallowed-positions-without-feature-gate.rs:27:9 + | +LL | if (let 2 = 3 && let 3 = 4 && let 4 = 5) {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: expected expression, found `let` statement + --> $DIR/disallowed-positions-without-feature-gate.rs:34:12 + | +LL | while (let 0 = 1) {} + | ^^^^^^^^^ + | + = note: only supported directly in conditions of `if` and `while` expressions +note: `let`s wrapped in parentheses are not supported in a context with let chains + --> $DIR/disallowed-positions-without-feature-gate.rs:34:12 + | +LL | while (let 0 = 1) {} + | ^^^^^^^^^ + +error: expected expression, found `let` statement + --> $DIR/disallowed-positions-without-feature-gate.rs:37:14 + | +LL | while (((let 0 = 1))) {} + | ^^^^^^^^^ + | + = note: only supported directly in conditions of `if` and `while` expressions +note: `let`s wrapped in parentheses are not supported in a context with let chains + --> $DIR/disallowed-positions-without-feature-gate.rs:37:14 + | +LL | while (((let 0 = 1))) {} + | ^^^^^^^^^ + +error: expected expression, found `let` statement + --> $DIR/disallowed-positions-without-feature-gate.rs:40:12 + | +LL | while (let 0 = 1) && true {} + | ^^^^^^^^^ + | + = note: only supported directly in conditions of `if` and `while` expressions +note: `let`s wrapped in parentheses are not supported in a context with let chains + --> $DIR/disallowed-positions-without-feature-gate.rs:40:12 + | +LL | while (let 0 = 1) && true {} + | ^^^^^^^^^ + +error: expected expression, found `let` statement + --> $DIR/disallowed-positions-without-feature-gate.rs:43:20 + | +LL | while true && (let 0 = 1) {} + | ^^^^^^^^^ + | + = note: only supported directly in conditions of `if` and `while` expressions +note: `let`s wrapped in parentheses are not supported in a context with let chains + --> $DIR/disallowed-positions-without-feature-gate.rs:43:20 + | +LL | while true && (let 0 = 1) {} + | ^^^^^^^^^ + +error: expected expression, found `let` statement + --> $DIR/disallowed-positions-without-feature-gate.rs:46:12 + | +LL | while (let 0 = 1) && (let 0 = 1) {} + | ^^^^^^^^^ + | + = note: only supported directly in conditions of `if` and `while` expressions +note: `let`s wrapped in parentheses are not supported in a context with let chains + --> $DIR/disallowed-positions-without-feature-gate.rs:46:12 + | +LL | while (let 0 = 1) && (let 0 = 1) {} + | ^^^^^^^^^ + +error: expected expression, found `let` statement + --> $DIR/disallowed-positions-without-feature-gate.rs:46:27 + | +LL | while (let 0 = 1) && (let 0 = 1) {} + | ^^^^^^^^^ + | + = note: only supported directly in conditions of `if` and `while` expressions +note: `let`s wrapped in parentheses are not supported in a context with let chains + --> $DIR/disallowed-positions-without-feature-gate.rs:46:27 + | +LL | while (let 0 = 1) && (let 0 = 1) {} + | ^^^^^^^^^ + +error: expected expression, found `let` statement + --> $DIR/disallowed-positions-without-feature-gate.rs:50:12 + | +LL | while (let 2 = 3 && let 3 = 4 && let 4 = 5) {} + | ^^^^^^^^^ + | + = note: only supported directly in conditions of `if` and `while` expressions +note: `let`s wrapped in parentheses are not supported in a context with let chains + --> $DIR/disallowed-positions-without-feature-gate.rs:50:12 + | +LL | while (let 2 = 3 && let 3 = 4 && let 4 = 5) {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: expected expression, found `let` statement + --> $DIR/disallowed-positions-without-feature-gate.rs:50:25 + | +LL | while (let 2 = 3 && let 3 = 4 && let 4 = 5) {} + | ^^^^^^^^^ + | + = note: only supported directly in conditions of `if` and `while` expressions +note: `let`s wrapped in parentheses are not supported in a context with let chains + --> $DIR/disallowed-positions-without-feature-gate.rs:50:12 + | +LL | while (let 2 = 3 && let 3 = 4 && let 4 = 5) {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: expected expression, found `let` statement + --> $DIR/disallowed-positions-without-feature-gate.rs:50:38 + | +LL | while (let 2 = 3 && let 3 = 4 && let 4 = 5) {} + | ^^^^^^^^^ + | + = note: only supported directly in conditions of `if` and `while` expressions +note: `let`s wrapped in parentheses are not supported in a context with let chains + --> $DIR/disallowed-positions-without-feature-gate.rs:50:12 + | +LL | while (let 2 = 3 && let 3 = 4 && let 4 = 5) {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: expected expression, found `let` statement + --> $DIR/disallowed-positions-without-feature-gate.rs:70:9 + | +LL | if &let 0 = 0 {} + | ^^^^^^^^^ + | + = note: only supported directly in conditions of `if` and `while` expressions + +error: expected expression, found `let` statement + --> $DIR/disallowed-positions-without-feature-gate.rs:73:9 + | +LL | if !let 0 = 0 {} + | ^^^^^^^^^ + | + = note: only supported directly in conditions of `if` and `while` expressions + +error: expected expression, found `let` statement + --> $DIR/disallowed-positions-without-feature-gate.rs:75:9 + | +LL | if *let 0 = 0 {} + | ^^^^^^^^^ + | + = note: only supported directly in conditions of `if` and `while` expressions + +error: expected expression, found `let` statement + --> $DIR/disallowed-positions-without-feature-gate.rs:77:9 + | +LL | if -let 0 = 0 {} + | ^^^^^^^^^ + | + = note: only supported directly in conditions of `if` and `while` expressions + +error: expected expression, found `let` statement + --> $DIR/disallowed-positions-without-feature-gate.rs:85:9 + | +LL | if (let 0 = 0)? {} + | ^^^^^^^^^ + | + = note: only supported directly in conditions of `if` and `while` expressions + +error: expected expression, found `let` statement + --> $DIR/disallowed-positions-without-feature-gate.rs:88:16 + | +LL | if true || let 0 = 0 {} + | ^^^^^^^^^ + | + = note: only supported directly in conditions of `if` and `while` expressions +note: `||` operators are not supported in let chain expressions + --> $DIR/disallowed-positions-without-feature-gate.rs:88:13 + | +LL | if true || let 0 = 0 {} + | ^^ + +error: expected expression, found `let` statement + --> $DIR/disallowed-positions-without-feature-gate.rs:90:17 + | +LL | if (true || let 0 = 0) {} + | ^^^^^^^^^ + | + = note: only supported directly in conditions of `if` and `while` expressions + +error: expected expression, found `let` statement + --> $DIR/disallowed-positions-without-feature-gate.rs:92:25 + | +LL | if true && (true || let 0 = 0) {} + | ^^^^^^^^^ + | + = note: only supported directly in conditions of `if` and `while` expressions + +error: expected expression, found `let` statement + --> $DIR/disallowed-positions-without-feature-gate.rs:94:25 + | +LL | if true || (true && let 0 = 0) {} + | ^^^^^^^^^ + | + = note: only supported directly in conditions of `if` and `while` expressions + +error: expected expression, found `let` statement + --> $DIR/disallowed-positions-without-feature-gate.rs:98:12 + | +LL | if x = let 0 = 0 {} + | ^^^ + | + = note: only supported directly in conditions of `if` and `while` expressions + +error: expected expression, found `let` statement + --> $DIR/disallowed-positions-without-feature-gate.rs:101:15 + | +LL | if true..(let 0 = 0) {} + | ^^^^^^^^^ + | + = note: only supported directly in conditions of `if` and `while` expressions + +error: expected expression, found `let` statement + --> $DIR/disallowed-positions-without-feature-gate.rs:104:11 + | +LL | if ..(let 0 = 0) {} + | ^^^^^^^^^ + | + = note: only supported directly in conditions of `if` and `while` expressions + +error: expected expression, found `let` statement + --> $DIR/disallowed-positions-without-feature-gate.rs:106:9 + | +LL | if (let 0 = 0).. {} + | ^^^^^^^^^ + | + = note: only supported directly in conditions of `if` and `while` expressions + +error: expected expression, found `let` statement + --> $DIR/disallowed-positions-without-feature-gate.rs:110:8 + | +LL | if let Range { start: _, end: _ } = true..true && false {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: only supported directly in conditions of `if` and `while` expressions + +error: expected expression, found `let` statement + --> $DIR/disallowed-positions-without-feature-gate.rs:113:8 + | +LL | if let Range { start: _, end: _ } = true..true || false {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: only supported directly in conditions of `if` and `while` expressions + +error: expected expression, found `let` statement + --> $DIR/disallowed-positions-without-feature-gate.rs:119:8 + | +LL | if let Range { start: F, end } = F..|| true {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: only supported directly in conditions of `if` and `while` expressions + +error: expected expression, found `let` statement + --> $DIR/disallowed-positions-without-feature-gate.rs:125:8 + | +LL | if let Range { start: true, end } = t..&&false {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: only supported directly in conditions of `if` and `while` expressions + +error: expected expression, found `let` statement + --> $DIR/disallowed-positions-without-feature-gate.rs:129:19 + | +LL | if let true = let true = true {} + | ^^^ + | + = note: only supported directly in conditions of `if` and `while` expressions + +error: expected expression, found `let` statement + --> $DIR/disallowed-positions-without-feature-gate.rs:134:12 + | +LL | while &let 0 = 0 {} + | ^^^^^^^^^ + | + = note: only supported directly in conditions of `if` and `while` expressions + +error: expected expression, found `let` statement + --> $DIR/disallowed-positions-without-feature-gate.rs:137:12 + | +LL | while !let 0 = 0 {} + | ^^^^^^^^^ + | + = note: only supported directly in conditions of `if` and `while` expressions + +error: expected expression, found `let` statement + --> $DIR/disallowed-positions-without-feature-gate.rs:139:12 + | +LL | while *let 0 = 0 {} + | ^^^^^^^^^ + | + = note: only supported directly in conditions of `if` and `while` expressions + +error: expected expression, found `let` statement + --> $DIR/disallowed-positions-without-feature-gate.rs:141:12 + | +LL | while -let 0 = 0 {} + | ^^^^^^^^^ + | + = note: only supported directly in conditions of `if` and `while` expressions + +error: expected expression, found `let` statement + --> $DIR/disallowed-positions-without-feature-gate.rs:149:12 + | +LL | while (let 0 = 0)? {} + | ^^^^^^^^^ + | + = note: only supported directly in conditions of `if` and `while` expressions + +error: expected expression, found `let` statement + --> $DIR/disallowed-positions-without-feature-gate.rs:152:19 + | +LL | while true || let 0 = 0 {} + | ^^^^^^^^^ + | + = note: only supported directly in conditions of `if` and `while` expressions +note: `||` operators are not supported in let chain expressions + --> $DIR/disallowed-positions-without-feature-gate.rs:152:16 + | +LL | while true || let 0 = 0 {} + | ^^ + +error: expected expression, found `let` statement + --> $DIR/disallowed-positions-without-feature-gate.rs:154:20 + | +LL | while (true || let 0 = 0) {} + | ^^^^^^^^^ + | + = note: only supported directly in conditions of `if` and `while` expressions + +error: expected expression, found `let` statement + --> $DIR/disallowed-positions-without-feature-gate.rs:156:28 + | +LL | while true && (true || let 0 = 0) {} + | ^^^^^^^^^ + | + = note: only supported directly in conditions of `if` and `while` expressions + +error: expected expression, found `let` statement + --> $DIR/disallowed-positions-without-feature-gate.rs:158:28 + | +LL | while true || (true && let 0 = 0) {} + | ^^^^^^^^^ + | + = note: only supported directly in conditions of `if` and `while` expressions + +error: expected expression, found `let` statement + --> $DIR/disallowed-positions-without-feature-gate.rs:162:15 + | +LL | while x = let 0 = 0 {} + | ^^^ + | + = note: only supported directly in conditions of `if` and `while` expressions + +error: expected expression, found `let` statement + --> $DIR/disallowed-positions-without-feature-gate.rs:165:18 + | +LL | while true..(let 0 = 0) {} + | ^^^^^^^^^ + | + = note: only supported directly in conditions of `if` and `while` expressions + +error: expected expression, found `let` statement + --> $DIR/disallowed-positions-without-feature-gate.rs:168:14 + | +LL | while ..(let 0 = 0) {} + | ^^^^^^^^^ + | + = note: only supported directly in conditions of `if` and `while` expressions + +error: expected expression, found `let` statement + --> $DIR/disallowed-positions-without-feature-gate.rs:170:12 + | +LL | while (let 0 = 0).. {} + | ^^^^^^^^^ + | + = note: only supported directly in conditions of `if` and `while` expressions + +error: expected expression, found `let` statement + --> $DIR/disallowed-positions-without-feature-gate.rs:174:11 + | +LL | while let Range { start: _, end: _ } = true..true && false {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: only supported directly in conditions of `if` and `while` expressions + +error: expected expression, found `let` statement + --> $DIR/disallowed-positions-without-feature-gate.rs:177:11 + | +LL | while let Range { start: _, end: _ } = true..true || false {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: only supported directly in conditions of `if` and `while` expressions + +error: expected expression, found `let` statement + --> $DIR/disallowed-positions-without-feature-gate.rs:183:11 + | +LL | while let Range { start: F, end } = F..|| true {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: only supported directly in conditions of `if` and `while` expressions + +error: expected expression, found `let` statement + --> $DIR/disallowed-positions-without-feature-gate.rs:189:11 + | +LL | while let Range { start: true, end } = t..&&false {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: only supported directly in conditions of `if` and `while` expressions + +error: expected expression, found `let` statement + --> $DIR/disallowed-positions-without-feature-gate.rs:193:22 + | +LL | while let true = let true = true {} + | ^^^ + | + = note: only supported directly in conditions of `if` and `while` expressions + +error: expected expression, found `let` statement + --> $DIR/disallowed-positions-without-feature-gate.rs:208:6 + | +LL | &let 0 = 0; + | ^^^ + | + = note: only supported directly in conditions of `if` and `while` expressions + +error: expected expression, found `let` statement + --> $DIR/disallowed-positions-without-feature-gate.rs:211:6 + | +LL | !let 0 = 0; + | ^^^ + | + = note: only supported directly in conditions of `if` and `while` expressions + +error: expected expression, found `let` statement + --> $DIR/disallowed-positions-without-feature-gate.rs:213:6 + | +LL | *let 0 = 0; + | ^^^ + | + = note: only supported directly in conditions of `if` and `while` expressions + +error: expected expression, found `let` statement + --> $DIR/disallowed-positions-without-feature-gate.rs:215:6 + | +LL | -let 0 = 0; + | ^^^ + | + = note: only supported directly in conditions of `if` and `while` expressions + +error: expected expression, found `let` statement + --> $DIR/disallowed-positions-without-feature-gate.rs:217:13 + | +LL | let _ = let _ = 3; + | ^^^ + | + = note: only supported directly in conditions of `if` and `while` expressions + +error: expected expression, found `let` statement + --> $DIR/disallowed-positions-without-feature-gate.rs:225:6 + | +LL | (let 0 = 0)?; + | ^^^ + | + = note: only supported directly in conditions of `if` and `while` expressions + +error: expected expression, found `let` statement + --> $DIR/disallowed-positions-without-feature-gate.rs:228:13 + | +LL | true || let 0 = 0; + | ^^^ + | + = note: only supported directly in conditions of `if` and `while` expressions + +error: expected expression, found `let` statement + --> $DIR/disallowed-positions-without-feature-gate.rs:230:14 + | +LL | (true || let 0 = 0); + | ^^^ + | + = note: only supported directly in conditions of `if` and `while` expressions + +error: expected expression, found `let` statement + --> $DIR/disallowed-positions-without-feature-gate.rs:232:22 + | +LL | true && (true || let 0 = 0); + | ^^^ + | + = note: only supported directly in conditions of `if` and `while` expressions + +error: expected expression, found `let` statement + --> $DIR/disallowed-positions-without-feature-gate.rs:236:9 + | +LL | x = let 0 = 0; + | ^^^ + | + = note: only supported directly in conditions of `if` and `while` expressions + +error: expected expression, found `let` statement + --> $DIR/disallowed-positions-without-feature-gate.rs:239:12 + | +LL | true..(let 0 = 0); + | ^^^ + | + = note: only supported directly in conditions of `if` and `while` expressions + +error: expected expression, found `let` statement + --> $DIR/disallowed-positions-without-feature-gate.rs:241:8 + | +LL | ..(let 0 = 0); + | ^^^ + | + = note: only supported directly in conditions of `if` and `while` expressions + +error: expected expression, found `let` statement + --> $DIR/disallowed-positions-without-feature-gate.rs:243:6 + | +LL | (let 0 = 0)..; + | ^^^ + | + = note: only supported directly in conditions of `if` and `while` expressions + +error: expected expression, found `let` statement + --> $DIR/disallowed-positions-without-feature-gate.rs:246:6 + | +LL | (let Range { start: _, end: _ } = true..true || false); + | ^^^ + | + = note: only supported directly in conditions of `if` and `while` expressions + +error: expected expression, found `let` statement + --> $DIR/disallowed-positions-without-feature-gate.rs:250:6 + | +LL | (let true = let true = true); + | ^^^ + | + = note: only supported directly in conditions of `if` and `while` expressions + +error: expected expression, found `let` statement + --> $DIR/disallowed-positions-without-feature-gate.rs:250:17 + | +LL | (let true = let true = true); + | ^^^ + | + = note: only supported directly in conditions of `if` and `while` expressions + +error: expected expression, found `let` statement + --> $DIR/disallowed-positions-without-feature-gate.rs:256:25 + | +LL | let x = true && let y = 1; + | ^^^ + | + = note: only supported directly in conditions of `if` and `while` expressions + +error: expected expression, found `let` statement + --> $DIR/disallowed-positions-without-feature-gate.rs:262:19 + | +LL | [1, 2, 3][let _ = ()] + | ^^^ + | + = note: only supported directly in conditions of `if` and `while` expressions + +error: expected expression, found `let` statement + --> $DIR/disallowed-positions-without-feature-gate.rs:267:6 + | +LL | &let 0 = 0 + | ^^^ + | + = note: only supported directly in conditions of `if` and `while` expressions + +error: expected expression, found `let` statement + --> $DIR/disallowed-positions-without-feature-gate.rs:277:17 + | +LL | true && let 1 = 1 + | ^^^ + | + = note: only supported directly in conditions of `if` and `while` expressions + +error: expected expression, found `let` statement + --> $DIR/disallowed-positions-without-feature-gate.rs:282:17 + | +LL | true && let 1 = 1 + | ^^^ + | + = note: only supported directly in conditions of `if` and `while` expressions + +error: expected expression, found `let` statement + --> $DIR/disallowed-positions-without-feature-gate.rs:287:17 + | +LL | true && let 1 = 1 + | ^^^ + | + = note: only supported directly in conditions of `if` and `while` expressions + +error: expected expression, found `let` statement + --> $DIR/disallowed-positions-without-feature-gate.rs:298:17 + | +LL | true && let 1 = 1 + | ^^^ + | + = note: only supported directly in conditions of `if` and `while` expressions + +error: expressions must be enclosed in braces to be used as const generic arguments + --> $DIR/disallowed-positions-without-feature-gate.rs:298:9 + | +LL | true && let 1 = 1 + | ^^^^^^^^^^^^^^^^^ + | +help: enclose the `const` expression in braces + | +LL | { true && let 1 = 1 } + | + + + +error: expected expression, found `let` statement + --> $DIR/disallowed-positions-without-feature-gate.rs:307:9 + | +LL | if (let Some(a) = opt && true) { + | ^^^^^^^^^^^^^^^^^ + | + = note: only supported directly in conditions of `if` and `while` expressions +note: `let`s wrapped in parentheses are not supported in a context with let chains + --> $DIR/disallowed-positions-without-feature-gate.rs:307:9 + | +LL | if (let Some(a) = opt && true) { + | ^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: expected expression, found `let` statement + --> $DIR/disallowed-positions-without-feature-gate.rs:311:9 + | +LL | if (let Some(a) = opt) && true { + | ^^^^^^^^^^^^^^^^^ + | + = note: only supported directly in conditions of `if` and `while` expressions +note: `let`s wrapped in parentheses are not supported in a context with let chains + --> $DIR/disallowed-positions-without-feature-gate.rs:311:9 + | +LL | if (let Some(a) = opt) && true { + | ^^^^^^^^^^^^^^^^^ + +error: expected expression, found `let` statement + --> $DIR/disallowed-positions-without-feature-gate.rs:314:9 + | +LL | if (let Some(a) = opt) && (let Some(b) = a) { + | ^^^^^^^^^^^^^^^^^ + | + = note: only supported directly in conditions of `if` and `while` expressions +note: `let`s wrapped in parentheses are not supported in a context with let chains + --> $DIR/disallowed-positions-without-feature-gate.rs:314:9 + | +LL | if (let Some(a) = opt) && (let Some(b) = a) { + | ^^^^^^^^^^^^^^^^^ + +error: expected expression, found `let` statement + --> $DIR/disallowed-positions-without-feature-gate.rs:314:32 + | +LL | if (let Some(a) = opt) && (let Some(b) = a) { + | ^^^^^^^^^^^^^^^ + | + = note: only supported directly in conditions of `if` and `while` expressions +note: `let`s wrapped in parentheses are not supported in a context with let chains + --> $DIR/disallowed-positions-without-feature-gate.rs:314:32 + | +LL | if (let Some(a) = opt) && (let Some(b) = a) { + | ^^^^^^^^^^^^^^^ + +error: expected expression, found `let` statement + --> $DIR/disallowed-positions-without-feature-gate.rs:319:9 + | +LL | if (let Some(a) = opt && (let Some(b) = a)) && b == 1 { + | ^^^^^^^^^^^^^^^^^ + | + = note: only supported directly in conditions of `if` and `while` expressions +note: `let`s wrapped in parentheses are not supported in a context with let chains + --> $DIR/disallowed-positions-without-feature-gate.rs:319:9 + | +LL | if (let Some(a) = opt && (let Some(b) = a)) && b == 1 { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: expected expression, found `let` statement + --> $DIR/disallowed-positions-without-feature-gate.rs:319:31 + | +LL | if (let Some(a) = opt && (let Some(b) = a)) && b == 1 { + | ^^^^^^^^^^^^^^^ + | + = note: only supported directly in conditions of `if` and `while` expressions +note: `let`s wrapped in parentheses are not supported in a context with let chains + --> $DIR/disallowed-positions-without-feature-gate.rs:319:31 + | +LL | if (let Some(a) = opt && (let Some(b) = a)) && b == 1 { + | ^^^^^^^^^^^^^^^ + +error: expected expression, found `let` statement + --> $DIR/disallowed-positions-without-feature-gate.rs:323:9 + | +LL | if (let Some(a) = opt && (let Some(b) = a)) && true { + | ^^^^^^^^^^^^^^^^^ + | + = note: only supported directly in conditions of `if` and `while` expressions +note: `let`s wrapped in parentheses are not supported in a context with let chains + --> $DIR/disallowed-positions-without-feature-gate.rs:323:9 + | +LL | if (let Some(a) = opt && (let Some(b) = a)) && true { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: expected expression, found `let` statement + --> $DIR/disallowed-positions-without-feature-gate.rs:323:31 + | +LL | if (let Some(a) = opt && (let Some(b) = a)) && true { + | ^^^^^^^^^^^^^^^ + | + = note: only supported directly in conditions of `if` and `while` expressions +note: `let`s wrapped in parentheses are not supported in a context with let chains + --> $DIR/disallowed-positions-without-feature-gate.rs:323:31 + | +LL | if (let Some(a) = opt && (let Some(b) = a)) && true { + | ^^^^^^^^^^^^^^^ + +error: expected expression, found `let` statement + --> $DIR/disallowed-positions-without-feature-gate.rs:327:9 + | +LL | if (let Some(a) = opt && (true)) && true { + | ^^^^^^^^^^^^^^^^^ + | + = note: only supported directly in conditions of `if` and `while` expressions +note: `let`s wrapped in parentheses are not supported in a context with let chains + --> $DIR/disallowed-positions-without-feature-gate.rs:327:9 + | +LL | if (let Some(a) = opt && (true)) && true { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: expected expression, found `let` statement + --> $DIR/disallowed-positions-without-feature-gate.rs:332:22 + | +LL | let x = (true && let y = 1); + | ^^^ + | + = note: only supported directly in conditions of `if` and `while` expressions + +error: expected expression, found `let` statement + --> $DIR/disallowed-positions-without-feature-gate.rs:337:20 + | +LL | ([1, 2, 3][let _ = ()]) + | ^^^ + | + = note: only supported directly in conditions of `if` and `while` expressions + +error: expected expression, found `let` statement + --> $DIR/disallowed-positions-without-feature-gate.rs:63:16 + | +LL | use_expr!((let 0 = 1 && 0 == 0)); + | ^^^ + | + = note: only supported directly in conditions of `if` and `while` expressions + +error: expected expression, found `let` statement + --> $DIR/disallowed-positions-without-feature-gate.rs:65:16 + | +LL | use_expr!((let 0 = 1)); + | ^^^ + | + = note: only supported directly in conditions of `if` and `while` expressions + +error[E0308]: mismatched types + --> $DIR/disallowed-positions-without-feature-gate.rs:101:8 + | +LL | if true..(let 0 = 0) {} + | ^^^^^^^^^^^^^^^^^ expected `bool`, found `Range<bool>` + | + = note: expected type `bool` + found struct `std::ops::Range<bool>` + +error[E0308]: mismatched types + --> $DIR/disallowed-positions-without-feature-gate.rs:110:12 + | +LL | if let Range { start: _, end: _ } = true..true && false {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ ---- this expression has type `bool` + | | + | expected `bool`, found `Range<_>` + | + = note: expected type `bool` + found struct `std::ops::Range<_>` + +error[E0308]: mismatched types + --> $DIR/disallowed-positions-without-feature-gate.rs:113:12 + | +LL | if let Range { start: _, end: _ } = true..true || false {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ ---- this expression has type `bool` + | | + | expected `bool`, found `Range<_>` + | + = note: expected type `bool` + found struct `std::ops::Range<_>` + +error[E0308]: mismatched types + --> $DIR/disallowed-positions-without-feature-gate.rs:119:12 + | +LL | if let Range { start: F, end } = F..|| true {} + | ^^^^^^^^^^^^^^^^^^^^^^^ - this expression has type `fn() -> bool` + | | + | expected fn pointer, found `Range<_>` + | + = note: expected fn pointer `fn() -> bool` + found struct `std::ops::Range<_>` + +error[E0308]: mismatched types + --> $DIR/disallowed-positions-without-feature-gate.rs:125:12 + | +LL | if let Range { start: true, end } = t..&&false {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ - this expression has type `&&bool` + | | + | expected `bool`, found `Range<_>` + | + = note: expected type `bool` + found struct `std::ops::Range<_>` + +error[E0277]: the `?` operator can only be applied to values that implement `Try` + --> $DIR/disallowed-positions-without-feature-gate.rs:81:20 + | +LL | if let 0 = 0? {} + | ^^ the `?` operator cannot be applied to type `{integer}` + | + = help: the trait `Try` is not implemented for `{integer}` + +error[E0308]: mismatched types + --> $DIR/disallowed-positions-without-feature-gate.rs:165:11 + | +LL | while true..(let 0 = 0) {} + | ^^^^^^^^^^^^^^^^^ expected `bool`, found `Range<bool>` + | + = note: expected type `bool` + found struct `std::ops::Range<bool>` + +error[E0308]: mismatched types + --> $DIR/disallowed-positions-without-feature-gate.rs:174:15 + | +LL | while let Range { start: _, end: _ } = true..true && false {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ ---- this expression has type `bool` + | | + | expected `bool`, found `Range<_>` + | + = note: expected type `bool` + found struct `std::ops::Range<_>` + +error[E0308]: mismatched types + --> $DIR/disallowed-positions-without-feature-gate.rs:177:15 + | +LL | while let Range { start: _, end: _ } = true..true || false {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ ---- this expression has type `bool` + | | + | expected `bool`, found `Range<_>` + | + = note: expected type `bool` + found struct `std::ops::Range<_>` + +error[E0308]: mismatched types + --> $DIR/disallowed-positions-without-feature-gate.rs:183:15 + | +LL | while let Range { start: F, end } = F..|| true {} + | ^^^^^^^^^^^^^^^^^^^^^^^ - this expression has type `fn() -> bool` + | | + | expected fn pointer, found `Range<_>` + | + = note: expected fn pointer `fn() -> bool` + found struct `std::ops::Range<_>` + +error[E0308]: mismatched types + --> $DIR/disallowed-positions-without-feature-gate.rs:189:15 + | +LL | while let Range { start: true, end } = t..&&false {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ - this expression has type `&&bool` + | | + | expected `bool`, found `Range<_>` + | + = note: expected type `bool` + found struct `std::ops::Range<_>` + +error[E0277]: the `?` operator can only be applied to values that implement `Try` + --> $DIR/disallowed-positions-without-feature-gate.rs:145:23 + | +LL | while let 0 = 0? {} + | ^^ the `?` operator cannot be applied to type `{integer}` + | + = help: the trait `Try` is not implemented for `{integer}` + +error[E0308]: mismatched types + --> $DIR/disallowed-positions-without-feature-gate.rs:246:10 + | +LL | (let Range { start: _, end: _ } = true..true || false); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ ---- this expression has type `bool` + | | + | expected `bool`, found `Range<_>` + | + = note: expected type `bool` + found struct `std::ops::Range<_>` + +error[E0277]: the `?` operator can only be applied to values that implement `Try` + --> $DIR/disallowed-positions-without-feature-gate.rs:221:17 + | +LL | let 0 = 0?; + | ^^ the `?` operator cannot be applied to type `{integer}` + | + = help: the trait `Try` is not implemented for `{integer}` + +error: aborting due to 105 previous errors + +Some errors have detailed explanations: E0277, E0308. +For more information about an error, try `rustc --explain E0277`. diff --git a/tests/ui/rfcs/rfc-2497-if-let-chains/disallowed-positions.rs b/tests/ui/rfcs/rfc-2497-if-let-chains/disallowed-positions.rs index 2a9a5472b2e..4ac3ea53a08 100644 --- a/tests/ui/rfcs/rfc-2497-if-let-chains/disallowed-positions.rs +++ b/tests/ui/rfcs/rfc-2497-if-let-chains/disallowed-positions.rs @@ -27,64 +27,46 @@ fn main() {} fn _if() { if (let 0 = 1) {} - //~^ ERROR `let` expressions are not supported here - //~| ERROR expected expression, found `let` statement + //~^ ERROR expected expression, found `let` statement if (((let 0 = 1))) {} - //~^ ERROR `let` expressions are not supported here - //~| ERROR expected expression, found `let` statement + //~^ ERROR expected expression, found `let` statement if (let 0 = 1) && true {} - //~^ ERROR `let` expressions are not supported here - //~| ERROR expected expression, found `let` statement + //~^ ERROR expected expression, found `let` statement if true && (let 0 = 1) {} - //~^ ERROR `let` expressions are not supported here - //~| ERROR expected expression, found `let` statement + //~^ ERROR expected expression, found `let` statement if (let 0 = 1) && (let 0 = 1) {} - //~^ ERROR `let` expressions are not supported here - //~| ERROR `let` expressions are not supported here - //~| ERROR expected expression, found `let` statement + //~^ ERROR expected expression, found `let` statement //~| ERROR expected expression, found `let` statement if let 0 = 1 && let 1 = 2 && (let 2 = 3 && let 3 = 4 && let 4 = 5) {} - //~^ ERROR `let` expressions are not supported here - //~| ERROR `let` expressions are not supported here - //~| ERROR `let` expressions are not supported here - //~| ERROR expected expression, found `let` statement + //~^ ERROR expected expression, found `let` statement //~| ERROR expected expression, found `let` statement //~| ERROR expected expression, found `let` statement } fn _while() { while (let 0 = 1) {} - //~^ ERROR `let` expressions are not supported here - //~| ERROR expected expression, found `let` statement + //~^ ERROR expected expression, found `let` statement while (((let 0 = 1))) {} - //~^ ERROR `let` expressions are not supported here - //~| ERROR expected expression, found `let` statement + //~^ ERROR expected expression, found `let` statement while (let 0 = 1) && true {} - //~^ ERROR `let` expressions are not supported here - //~| ERROR expected expression, found `let` statement + //~^ ERROR expected expression, found `let` statement while true && (let 0 = 1) {} - //~^ ERROR `let` expressions are not supported here - //~| ERROR expected expression, found `let` statement + //~^ ERROR expected expression, found `let` statement while (let 0 = 1) && (let 0 = 1) {} - //~^ ERROR `let` expressions are not supported here - //~| ERROR `let` expressions are not supported here - //~| ERROR expected expression, found `let` statement + //~^ ERROR expected expression, found `let` statement //~| ERROR expected expression, found `let` statement while let 0 = 1 && let 1 = 2 && (let 2 = 3 && let 3 = 4 && let 4 = 5) {} - //~^ ERROR `let` expressions are not supported here - //~| ERROR `let` expressions are not supported here - //~| ERROR `let` expressions are not supported here - //~| ERROR expected expression, found `let` statement + //~^ ERROR expected expression, found `let` statement //~| ERROR expected expression, found `let` statement //~| ERROR expected expression, found `let` statement } @@ -97,32 +79,21 @@ fn _macros() { } } use_expr!((let 0 = 1 && 0 == 0)); - //~^ ERROR `let` expressions are not supported here - //~| ERROR `let` expressions are not supported here - //~| ERROR expected expression, found `let` statement + //~^ ERROR expected expression, found `let` statement use_expr!((let 0 = 1)); - //~^ ERROR `let` expressions are not supported here - //~| ERROR `let` expressions are not supported here - //~| ERROR expected expression, found `let` statement + //~^ ERROR expected expression, found `let` statement } fn nested_within_if_expr() { if &let 0 = 0 {} - //~^ ERROR `let` expressions are not supported here - //~| ERROR mismatched types - //~| ERROR expected expression, found `let` statement + //~^ ERROR expected expression, found `let` statement if !let 0 = 0 {} - //~^ ERROR `let` expressions are not supported here - //~| ERROR expected expression, found `let` statement + //~^ ERROR expected expression, found `let` statement if *let 0 = 0 {} - //~^ ERROR `let` expressions are not supported here - //~| ERROR type `bool` cannot be dereferenced - //~| ERROR expected expression, found `let` statement + //~^ ERROR expected expression, found `let` statement if -let 0 = 0 {} - //~^ ERROR `let` expressions are not supported here - //~| ERROR cannot apply unary operator `-` to type `bool` - //~| ERROR expected expression, found `let` statement + //~^ ERROR expected expression, found `let` statement fn _check_try_binds_tighter() -> Result<(), ()> { if let 0 = 0? {} @@ -130,91 +101,63 @@ fn nested_within_if_expr() { Ok(()) } if (let 0 = 0)? {} - //~^ ERROR `let` expressions are not supported here - //~| ERROR the `?` operator can only be applied to values that implement `Try` - //~| ERROR the `?` operator can only be used in a function that returns `Result` - //~| ERROR expected expression, found `let` statement + //~^ ERROR expected expression, found `let` statement if true || let 0 = 0 {} - //~^ ERROR `let` expressions are not supported here - //~| ERROR expected expression, found `let` statement + //~^ ERROR expected expression, found `let` statement if (true || let 0 = 0) {} - //~^ ERROR `let` expressions are not supported here - //~| ERROR expected expression, found `let` statement + //~^ ERROR expected expression, found `let` statement if true && (true || let 0 = 0) {} - //~^ ERROR `let` expressions are not supported here - //~| ERROR expected expression, found `let` statement + //~^ ERROR expected expression, found `let` statement if true || (true && let 0 = 0) {} - //~^ ERROR `let` expressions are not supported here - //~| ERROR expected expression, found `let` statement + //~^ ERROR expected expression, found `let` statement let mut x = true; if x = let 0 = 0 {} - //~^ ERROR `let` expressions are not supported here - //~| ERROR mismatched types - //~| ERROR expected expression, found `let` statement + //~^ ERROR expected expression, found `let` statement if true..(let 0 = 0) {} - //~^ ERROR `let` expressions are not supported here + //~^ ERROR expected expression, found `let` statement //~| ERROR mismatched types - //~| ERROR expected expression, found `let` statement if ..(let 0 = 0) {} - //~^ ERROR `let` expressions are not supported here - //~| ERROR mismatched types - //~| ERROR expected expression, found `let` statement + //~^ ERROR expected expression, found `let` statement if (let 0 = 0).. {} - //~^ ERROR `let` expressions are not supported here - //~| ERROR mismatched types - //~| ERROR expected expression, found `let` statement + //~^ ERROR expected expression, found `let` statement // Binds as `(let ... = true)..true &&/|| false`. if let Range { start: _, end: _ } = true..true && false {} - //~^ ERROR `let` expressions are not supported here - //~| ERROR mismatched types + //~^ ERROR expected expression, found `let` statement //~| ERROR mismatched types if let Range { start: _, end: _ } = true..true || false {} - //~^ ERROR `let` expressions are not supported here - //~| ERROR mismatched types + //~^ ERROR expected expression, found `let` statement //~| ERROR mismatched types // Binds as `(let Range { start: F, end } = F)..(|| true)`. const F: fn() -> bool = || true; if let Range { start: F, end } = F..|| true {} - //~^ ERROR `let` expressions are not supported here - //~| ERROR mismatched types - //~| ERROR mismatched types + //~^ ERROR expected expression, found `let` statement //~| ERROR mismatched types // Binds as `(let Range { start: true, end } = t)..(&&false)`. let t = &&true; if let Range { start: true, end } = t..&&false {} - //~^ ERROR `let` expressions are not supported here - //~| ERROR mismatched types - //~| ERROR mismatched types + //~^ ERROR expected expression, found `let` statement //~| ERROR mismatched types if let true = let true = true {} - //~^ ERROR `let` expressions are not supported here - //~| ERROR expected expression, found `let` statement + //~^ ERROR expected expression, found `let` statement } fn nested_within_while_expr() { while &let 0 = 0 {} - //~^ ERROR `let` expressions are not supported here - //~| ERROR mismatched types - //~| ERROR expected expression, found `let` statement + //~^ ERROR expected expression, found `let` statement while !let 0 = 0 {} - //~^ ERROR `let` expressions are not supported here - //~| ERROR expected expression, found `let` statement + //~^ ERROR expected expression, found `let` statement while *let 0 = 0 {} - //~^ ERROR `let` expressions are not supported here - //~| ERROR type `bool` cannot be dereferenced - //~| ERROR expected expression, found `let` statement + //~^ ERROR expected expression, found `let` statement while -let 0 = 0 {} - //~^ ERROR `let` expressions are not supported here - //~| ERROR cannot apply unary operator `-` to type `bool` - //~| ERROR expected expression, found `let` statement + //~^ ERROR expected expression, found `let` statement fn _check_try_binds_tighter() -> Result<(), ()> { while let 0 = 0? {} @@ -222,72 +165,51 @@ fn nested_within_while_expr() { Ok(()) } while (let 0 = 0)? {} - //~^ ERROR `let` expressions are not supported here - //~| ERROR the `?` operator can only be applied to values that implement `Try` - //~| ERROR the `?` operator can only be used in a function that returns `Result` - //~| ERROR expected expression, found `let` statement + //~^ ERROR expected expression, found `let` statement while true || let 0 = 0 {} - //~^ ERROR `let` expressions are not supported here - //~| ERROR expected expression, found `let` statement + //~^ ERROR expected expression, found `let` statement while (true || let 0 = 0) {} - //~^ ERROR `let` expressions are not supported here - //~| ERROR expected expression, found `let` statement + //~^ ERROR expected expression, found `let` statement while true && (true || let 0 = 0) {} - //~^ ERROR `let` expressions are not supported here - //~| ERROR expected expression, found `let` statement + //~^ ERROR expected expression, found `let` statement while true || (true && let 0 = 0) {} - //~^ ERROR `let` expressions are not supported here - //~| ERROR expected expression, found `let` statement + //~^ ERROR expected expression, found `let` statement let mut x = true; while x = let 0 = 0 {} - //~^ ERROR `let` expressions are not supported here - //~| ERROR mismatched types - //~| ERROR expected expression, found `let` statement + //~^ ERROR expected expression, found `let` statement while true..(let 0 = 0) {} - //~^ ERROR `let` expressions are not supported here + //~^ ERROR expected expression, found `let` statement //~| ERROR mismatched types - //~| ERROR expected expression, found `let` statement while ..(let 0 = 0) {} - //~^ ERROR `let` expressions are not supported here - //~| ERROR mismatched types - //~| ERROR expected expression, found `let` statement + //~^ ERROR expected expression, found `let` statement while (let 0 = 0).. {} - //~^ ERROR `let` expressions are not supported here - //~| ERROR mismatched types - //~| ERROR expected expression, found `let` statement + //~^ ERROR expected expression, found `let` statement // Binds as `(let ... = true)..true &&/|| false`. while let Range { start: _, end: _ } = true..true && false {} - //~^ ERROR `let` expressions are not supported here - //~| ERROR mismatched types + //~^ ERROR expected expression, found `let` statement //~| ERROR mismatched types while let Range { start: _, end: _ } = true..true || false {} - //~^ ERROR `let` expressions are not supported here - //~| ERROR mismatched types + //~^ ERROR expected expression, found `let` statement //~| ERROR mismatched types // Binds as `(let Range { start: F, end } = F)..(|| true)`. const F: fn() -> bool = || true; while let Range { start: F, end } = F..|| true {} - //~^ ERROR `let` expressions are not supported here - //~| ERROR mismatched types - //~| ERROR mismatched types + //~^ ERROR expected expression, found `let` statement //~| ERROR mismatched types // Binds as `(let Range { start: true, end } = t)..(&&false)`. let t = &&true; while let Range { start: true, end } = t..&&false {} - //~^ ERROR `let` expressions are not supported here - //~| ERROR mismatched types - //~| ERROR mismatched types + //~^ ERROR expected expression, found `let` statement //~| ERROR mismatched types while let true = let true = true {} - //~^ ERROR `let` expressions are not supported here - //~| ERROR expected expression, found `let` statement + //~^ ERROR expected expression, found `let` statement } fn not_error_because_clarified_intent() { @@ -302,20 +224,14 @@ fn not_error_because_clarified_intent() { fn outside_if_and_while_expr() { &let 0 = 0; - //~^ ERROR `let` expressions are not supported here - //~| ERROR expected expression, found `let` statement + //~^ ERROR expected expression, found `let` statement !let 0 = 0; - //~^ ERROR `let` expressions are not supported here - //~| ERROR expected expression, found `let` statement + //~^ ERROR expected expression, found `let` statement *let 0 = 0; - //~^ ERROR `let` expressions are not supported here - //~| ERROR type `bool` cannot be dereferenced - //~| ERROR expected expression, found `let` statement + //~^ ERROR expected expression, found `let` statement -let 0 = 0; - //~^ ERROR `let` expressions are not supported here - //~| ERROR cannot apply unary operator `-` to type `bool` - //~| ERROR expected expression, found `let` statement + //~^ ERROR expected expression, found `let` statement fn _check_try_binds_tighter() -> Result<(), ()> { let 0 = 0?; @@ -323,44 +239,32 @@ fn outside_if_and_while_expr() { Ok(()) } (let 0 = 0)?; - //~^ ERROR `let` expressions are not supported here - //~| ERROR the `?` operator can only be used in a function that returns `Result` - //~| ERROR the `?` operator can only be applied to values that implement `Try` - //~| ERROR expected expression, found `let` statement + //~^ ERROR expected expression, found `let` statement true || let 0 = 0; - //~^ ERROR `let` expressions are not supported here - //~| ERROR expected expression, found `let` statement + //~^ ERROR expected expression, found `let` statement (true || let 0 = 0); - //~^ ERROR `let` expressions are not supported here - //~| ERROR expected expression, found `let` statement + //~^ ERROR expected expression, found `let` statement true && (true || let 0 = 0); - //~^ ERROR `let` expressions are not supported here - //~| ERROR expected expression, found `let` statement + //~^ ERROR expected expression, found `let` statement let mut x = true; x = let 0 = 0; - //~^ ERROR `let` expressions are not supported here - //~| ERROR expected expression, found `let` statement + //~^ ERROR expected expression, found `let` statement true..(let 0 = 0); - //~^ ERROR `let` expressions are not supported here - //~| ERROR expected expression, found `let` statement + //~^ ERROR expected expression, found `let` statement ..(let 0 = 0); - //~^ ERROR `let` expressions are not supported here - //~| ERROR expected expression, found `let` statement + //~^ ERROR expected expression, found `let` statement (let 0 = 0)..; - //~^ ERROR `let` expressions are not supported here - //~| ERROR expected expression, found `let` statement + //~^ ERROR expected expression, found `let` statement (let Range { start: _, end: _ } = true..true || false); - //~^ ERROR `let` expressions are not supported here - //~| ERROR mismatched types + //~^ ERROR mismatched types //~| ERROR expected expression, found `let` statement (let true = let true = true); - //~^ ERROR `let` expressions are not supported here - //~| ERROR expected expression, found `let` statement + //~^ ERROR expected expression, found `let` statement //~| ERROR expected expression, found `let` statement { @@ -377,9 +281,7 @@ fn outside_if_and_while_expr() { // Check function tail position. &let 0 = 0 - //~^ ERROR `let` expressions are not supported here - //~| ERROR mismatched types - //~| ERROR expected expression, found `let` statement + //~^ ERROR expected expression, found `let` statement } // Let's make sure that `let` inside const generic arguments are considered. @@ -389,20 +291,17 @@ fn inside_const_generic_arguments() { if let A::<{ true && let 1 = 1 - //~^ ERROR `let` expressions are not supported here - //~| ERROR expected expression, found `let` statement + //~^ ERROR expected expression, found `let` statement }>::O = 5 {} while let A::<{ true && let 1 = 1 - //~^ ERROR `let` expressions are not supported here - //~| ERROR expected expression, found `let` statement + //~^ ERROR expected expression, found `let` statement }>::O = 5 {} if A::<{ true && let 1 = 1 - //~^ ERROR `let` expressions are not supported here - //~| ERROR expected expression, found `let` statement + //~^ ERROR expected expression, found `let` statement }>::O == 5 {} // In the cases above we have `ExprKind::Block` to help us out. @@ -413,8 +312,7 @@ fn inside_const_generic_arguments() { if A::< true && let 1 = 1 - //~^ ERROR `let` expressions are not supported here - //~| ERROR expressions must be enclosed in braces + //~^ ERROR expressions must be enclosed in braces //~| ERROR expected expression, found `let` statement >::O == 5 {} } @@ -423,38 +321,29 @@ fn with_parenthesis() { let opt = Some(Some(1i32)); if (let Some(a) = opt && true) { - //~^ ERROR `let` expressions are not supported here - //~| ERROR expected expression, found `let` statement + //~^ ERROR expected expression, found `let` statement } if (let Some(a) = opt) && true { - //~^ ERROR `let` expressions are not supported here - //~| ERROR expected expression, found `let` statement + //~^ ERROR expected expression, found `let` statement } if (let Some(a) = opt) && (let Some(b) = a) { - //~^ ERROR `let` expressions are not supported here - //~| ERROR `let` expressions are not supported here - //~| ERROR expected expression, found `let` statement + //~^ ERROR expected expression, found `let` statement //~| ERROR expected expression, found `let` statement } if let Some(a) = opt && (true && true) { } if (let Some(a) = opt && (let Some(b) = a)) && b == 1 { - //~^ ERROR `let` expressions are not supported here - //~| ERROR `let` expressions are not supported here - //~| ERROR expected expression, found `let` statement + //~^ ERROR expected expression, found `let` statement //~| ERROR expected expression, found `let` statement } if (let Some(a) = opt && (let Some(b) = a)) && true { - //~^ ERROR `let` expressions are not supported here - //~| ERROR `let` expressions are not supported here - //~| ERROR expected expression, found `let` statement + //~^ ERROR expected expression, found `let` statement //~| ERROR expected expression, found `let` statement } if (let Some(a) = opt && (true)) && true { - //~^ ERROR `let` expressions are not supported here - //~| ERROR expected expression, found `let` statement + //~^ ERROR expected expression, found `let` statement } if (true && (true)) && let Some(a) = opt { diff --git a/tests/ui/rfcs/rfc-2497-if-let-chains/disallowed-positions.stderr b/tests/ui/rfcs/rfc-2497-if-let-chains/disallowed-positions.stderr index 81933173c25..ab58abf4d46 100644 --- a/tests/ui/rfcs/rfc-2497-if-let-chains/disallowed-positions.stderr +++ b/tests/ui/rfcs/rfc-2497-if-let-chains/disallowed-positions.stderr @@ -2,503 +2,6 @@ error: expected expression, found `let` statement --> $DIR/disallowed-positions.rs:29:9 | LL | if (let 0 = 1) {} - | ^^^ - -error: expected expression, found `let` statement - --> $DIR/disallowed-positions.rs:33:11 - | -LL | if (((let 0 = 1))) {} - | ^^^ - -error: expected expression, found `let` statement - --> $DIR/disallowed-positions.rs:37:9 - | -LL | if (let 0 = 1) && true {} - | ^^^ - -error: expected expression, found `let` statement - --> $DIR/disallowed-positions.rs:41:17 - | -LL | if true && (let 0 = 1) {} - | ^^^ - -error: expected expression, found `let` statement - --> $DIR/disallowed-positions.rs:45:9 - | -LL | if (let 0 = 1) && (let 0 = 1) {} - | ^^^ - -error: expected expression, found `let` statement - --> $DIR/disallowed-positions.rs:45:24 - | -LL | if (let 0 = 1) && (let 0 = 1) {} - | ^^^ - -error: expected expression, found `let` statement - --> $DIR/disallowed-positions.rs:51:35 - | -LL | if let 0 = 1 && let 1 = 2 && (let 2 = 3 && let 3 = 4 && let 4 = 5) {} - | ^^^ - -error: expected expression, found `let` statement - --> $DIR/disallowed-positions.rs:51:48 - | -LL | if let 0 = 1 && let 1 = 2 && (let 2 = 3 && let 3 = 4 && let 4 = 5) {} - | ^^^ - -error: expected expression, found `let` statement - --> $DIR/disallowed-positions.rs:51:61 - | -LL | if let 0 = 1 && let 1 = 2 && (let 2 = 3 && let 3 = 4 && let 4 = 5) {} - | ^^^ - -error: expected expression, found `let` statement - --> $DIR/disallowed-positions.rs:61:12 - | -LL | while (let 0 = 1) {} - | ^^^ - -error: expected expression, found `let` statement - --> $DIR/disallowed-positions.rs:65:14 - | -LL | while (((let 0 = 1))) {} - | ^^^ - -error: expected expression, found `let` statement - --> $DIR/disallowed-positions.rs:69:12 - | -LL | while (let 0 = 1) && true {} - | ^^^ - -error: expected expression, found `let` statement - --> $DIR/disallowed-positions.rs:73:20 - | -LL | while true && (let 0 = 1) {} - | ^^^ - -error: expected expression, found `let` statement - --> $DIR/disallowed-positions.rs:77:12 - | -LL | while (let 0 = 1) && (let 0 = 1) {} - | ^^^ - -error: expected expression, found `let` statement - --> $DIR/disallowed-positions.rs:77:27 - | -LL | while (let 0 = 1) && (let 0 = 1) {} - | ^^^ - -error: expected expression, found `let` statement - --> $DIR/disallowed-positions.rs:83:38 - | -LL | while let 0 = 1 && let 1 = 2 && (let 2 = 3 && let 3 = 4 && let 4 = 5) {} - | ^^^ - -error: expected expression, found `let` statement - --> $DIR/disallowed-positions.rs:83:51 - | -LL | while let 0 = 1 && let 1 = 2 && (let 2 = 3 && let 3 = 4 && let 4 = 5) {} - | ^^^ - -error: expected expression, found `let` statement - --> $DIR/disallowed-positions.rs:83:64 - | -LL | while let 0 = 1 && let 1 = 2 && (let 2 = 3 && let 3 = 4 && let 4 = 5) {} - | ^^^ - -error: expected expression, found `let` statement - --> $DIR/disallowed-positions.rs:110:9 - | -LL | if &let 0 = 0 {} - | ^^^ - -error: expected expression, found `let` statement - --> $DIR/disallowed-positions.rs:115:9 - | -LL | if !let 0 = 0 {} - | ^^^ - -error: expected expression, found `let` statement - --> $DIR/disallowed-positions.rs:118:9 - | -LL | if *let 0 = 0 {} - | ^^^ - -error: expected expression, found `let` statement - --> $DIR/disallowed-positions.rs:122:9 - | -LL | if -let 0 = 0 {} - | ^^^ - -error: expected expression, found `let` statement - --> $DIR/disallowed-positions.rs:132:9 - | -LL | if (let 0 = 0)? {} - | ^^^ - -error: expected expression, found `let` statement - --> $DIR/disallowed-positions.rs:138:16 - | -LL | if true || let 0 = 0 {} - | ^^^ - -error: expected expression, found `let` statement - --> $DIR/disallowed-positions.rs:141:17 - | -LL | if (true || let 0 = 0) {} - | ^^^ - -error: expected expression, found `let` statement - --> $DIR/disallowed-positions.rs:144:25 - | -LL | if true && (true || let 0 = 0) {} - | ^^^ - -error: expected expression, found `let` statement - --> $DIR/disallowed-positions.rs:147:25 - | -LL | if true || (true && let 0 = 0) {} - | ^^^ - -error: expected expression, found `let` statement - --> $DIR/disallowed-positions.rs:152:12 - | -LL | if x = let 0 = 0 {} - | ^^^ - -error: expected expression, found `let` statement - --> $DIR/disallowed-positions.rs:157:15 - | -LL | if true..(let 0 = 0) {} - | ^^^ - -error: expected expression, found `let` statement - --> $DIR/disallowed-positions.rs:161:11 - | -LL | if ..(let 0 = 0) {} - | ^^^ - -error: expected expression, found `let` statement - --> $DIR/disallowed-positions.rs:165:9 - | -LL | if (let 0 = 0).. {} - | ^^^ - -error: expected expression, found `let` statement - --> $DIR/disallowed-positions.rs:196:19 - | -LL | if let true = let true = true {} - | ^^^ - -error: expected expression, found `let` statement - --> $DIR/disallowed-positions.rs:202:12 - | -LL | while &let 0 = 0 {} - | ^^^ - -error: expected expression, found `let` statement - --> $DIR/disallowed-positions.rs:207:12 - | -LL | while !let 0 = 0 {} - | ^^^ - -error: expected expression, found `let` statement - --> $DIR/disallowed-positions.rs:210:12 - | -LL | while *let 0 = 0 {} - | ^^^ - -error: expected expression, found `let` statement - --> $DIR/disallowed-positions.rs:214:12 - | -LL | while -let 0 = 0 {} - | ^^^ - -error: expected expression, found `let` statement - --> $DIR/disallowed-positions.rs:224:12 - | -LL | while (let 0 = 0)? {} - | ^^^ - -error: expected expression, found `let` statement - --> $DIR/disallowed-positions.rs:230:19 - | -LL | while true || let 0 = 0 {} - | ^^^ - -error: expected expression, found `let` statement - --> $DIR/disallowed-positions.rs:233:20 - | -LL | while (true || let 0 = 0) {} - | ^^^ - -error: expected expression, found `let` statement - --> $DIR/disallowed-positions.rs:236:28 - | -LL | while true && (true || let 0 = 0) {} - | ^^^ - -error: expected expression, found `let` statement - --> $DIR/disallowed-positions.rs:239:28 - | -LL | while true || (true && let 0 = 0) {} - | ^^^ - -error: expected expression, found `let` statement - --> $DIR/disallowed-positions.rs:244:15 - | -LL | while x = let 0 = 0 {} - | ^^^ - -error: expected expression, found `let` statement - --> $DIR/disallowed-positions.rs:249:18 - | -LL | while true..(let 0 = 0) {} - | ^^^ - -error: expected expression, found `let` statement - --> $DIR/disallowed-positions.rs:253:14 - | -LL | while ..(let 0 = 0) {} - | ^^^ - -error: expected expression, found `let` statement - --> $DIR/disallowed-positions.rs:257:12 - | -LL | while (let 0 = 0).. {} - | ^^^ - -error: expected expression, found `let` statement - --> $DIR/disallowed-positions.rs:288:22 - | -LL | while let true = let true = true {} - | ^^^ - -error: expected expression, found `let` statement - --> $DIR/disallowed-positions.rs:304:6 - | -LL | &let 0 = 0; - | ^^^ - -error: expected expression, found `let` statement - --> $DIR/disallowed-positions.rs:308:6 - | -LL | !let 0 = 0; - | ^^^ - -error: expected expression, found `let` statement - --> $DIR/disallowed-positions.rs:311:6 - | -LL | *let 0 = 0; - | ^^^ - -error: expected expression, found `let` statement - --> $DIR/disallowed-positions.rs:315:6 - | -LL | -let 0 = 0; - | ^^^ - -error: expected expression, found `let` statement - --> $DIR/disallowed-positions.rs:325:6 - | -LL | (let 0 = 0)?; - | ^^^ - -error: expected expression, found `let` statement - --> $DIR/disallowed-positions.rs:331:13 - | -LL | true || let 0 = 0; - | ^^^ - -error: expected expression, found `let` statement - --> $DIR/disallowed-positions.rs:334:14 - | -LL | (true || let 0 = 0); - | ^^^ - -error: expected expression, found `let` statement - --> $DIR/disallowed-positions.rs:337:22 - | -LL | true && (true || let 0 = 0); - | ^^^ - -error: expected expression, found `let` statement - --> $DIR/disallowed-positions.rs:342:9 - | -LL | x = let 0 = 0; - | ^^^ - -error: expected expression, found `let` statement - --> $DIR/disallowed-positions.rs:346:12 - | -LL | true..(let 0 = 0); - | ^^^ - -error: expected expression, found `let` statement - --> $DIR/disallowed-positions.rs:349:8 - | -LL | ..(let 0 = 0); - | ^^^ - -error: expected expression, found `let` statement - --> $DIR/disallowed-positions.rs:352:6 - | -LL | (let 0 = 0)..; - | ^^^ - -error: expected expression, found `let` statement - --> $DIR/disallowed-positions.rs:356:6 - | -LL | (let Range { start: _, end: _ } = true..true || false); - | ^^^ - -error: expected expression, found `let` statement - --> $DIR/disallowed-positions.rs:361:6 - | -LL | (let true = let true = true); - | ^^^ - -error: expected expression, found `let` statement - --> $DIR/disallowed-positions.rs:361:17 - | -LL | (let true = let true = true); - | ^^^ - -error: expected expression, found `let` statement - --> $DIR/disallowed-positions.rs:368:25 - | -LL | let x = true && let y = 1; - | ^^^ - -error: expected expression, found `let` statement - --> $DIR/disallowed-positions.rs:374:19 - | -LL | [1, 2, 3][let _ = ()] - | ^^^ - -error: expected expression, found `let` statement - --> $DIR/disallowed-positions.rs:379:6 - | -LL | &let 0 = 0 - | ^^^ - -error: expected expression, found `let` statement - --> $DIR/disallowed-positions.rs:391:17 - | -LL | true && let 1 = 1 - | ^^^ - -error: expected expression, found `let` statement - --> $DIR/disallowed-positions.rs:397:17 - | -LL | true && let 1 = 1 - | ^^^ - -error: expected expression, found `let` statement - --> $DIR/disallowed-positions.rs:403:17 - | -LL | true && let 1 = 1 - | ^^^ - -error: expected expression, found `let` statement - --> $DIR/disallowed-positions.rs:415:17 - | -LL | true && let 1 = 1 - | ^^^ - -error: expressions must be enclosed in braces to be used as const generic arguments - --> $DIR/disallowed-positions.rs:415:9 - | -LL | true && let 1 = 1 - | ^^^^^^^^^^^^^^^^^ - | -help: enclose the `const` expression in braces - | -LL | { true && let 1 = 1 } - | + + - -error: expected expression, found `let` statement - --> $DIR/disallowed-positions.rs:425:9 - | -LL | if (let Some(a) = opt && true) { - | ^^^ - -error: expected expression, found `let` statement - --> $DIR/disallowed-positions.rs:430:9 - | -LL | if (let Some(a) = opt) && true { - | ^^^ - -error: expected expression, found `let` statement - --> $DIR/disallowed-positions.rs:434:9 - | -LL | if (let Some(a) = opt) && (let Some(b) = a) { - | ^^^ - -error: expected expression, found `let` statement - --> $DIR/disallowed-positions.rs:434:32 - | -LL | if (let Some(a) = opt) && (let Some(b) = a) { - | ^^^ - -error: expected expression, found `let` statement - --> $DIR/disallowed-positions.rs:443:9 - | -LL | if (let Some(a) = opt && (let Some(b) = a)) && b == 1 { - | ^^^ - -error: expected expression, found `let` statement - --> $DIR/disallowed-positions.rs:443:31 - | -LL | if (let Some(a) = opt && (let Some(b) = a)) && b == 1 { - | ^^^ - -error: expected expression, found `let` statement - --> $DIR/disallowed-positions.rs:449:9 - | -LL | if (let Some(a) = opt && (let Some(b) = a)) && true { - | ^^^ - -error: expected expression, found `let` statement - --> $DIR/disallowed-positions.rs:449:31 - | -LL | if (let Some(a) = opt && (let Some(b) = a)) && true { - | ^^^ - -error: expected expression, found `let` statement - --> $DIR/disallowed-positions.rs:455:9 - | -LL | if (let Some(a) = opt && (true)) && true { - | ^^^ - -error: expected expression, found `let` statement - --> $DIR/disallowed-positions.rs:472:22 - | -LL | let x = (true && let y = 1); - | ^^^ - -error: expected expression, found `let` statement - --> $DIR/disallowed-positions.rs:477:20 - | -LL | ([1, 2, 3][let _ = ()]) - | ^^^ - -error: expected expression, found `let` statement - --> $DIR/disallowed-positions.rs:99:16 - | -LL | use_expr!((let 0 = 1 && 0 == 0)); - | ^^^ - -error: expected expression, found `let` statement - --> $DIR/disallowed-positions.rs:103:16 - | -LL | use_expr!((let 0 = 1)); - | ^^^ - -error: `let` expressions are not supported here - --> $DIR/disallowed-positions.rs:29:9 - | -LL | if (let 0 = 1) {} | ^^^^^^^^^ | = note: only supported directly in conditions of `if` and `while` expressions @@ -508,1012 +11,863 @@ note: `let`s wrapped in parentheses are not supported in a context with let chai LL | if (let 0 = 1) {} | ^^^^^^^^^ -error: `let` expressions are not supported here - --> $DIR/disallowed-positions.rs:33:11 +error: expected expression, found `let` statement + --> $DIR/disallowed-positions.rs:32:11 | LL | if (((let 0 = 1))) {} | ^^^^^^^^^ | = note: only supported directly in conditions of `if` and `while` expressions note: `let`s wrapped in parentheses are not supported in a context with let chains - --> $DIR/disallowed-positions.rs:33:11 + --> $DIR/disallowed-positions.rs:32:11 | LL | if (((let 0 = 1))) {} | ^^^^^^^^^ -error: `let` expressions are not supported here - --> $DIR/disallowed-positions.rs:37:9 +error: expected expression, found `let` statement + --> $DIR/disallowed-positions.rs:35:9 | LL | if (let 0 = 1) && true {} | ^^^^^^^^^ | = note: only supported directly in conditions of `if` and `while` expressions note: `let`s wrapped in parentheses are not supported in a context with let chains - --> $DIR/disallowed-positions.rs:37:9 + --> $DIR/disallowed-positions.rs:35:9 | LL | if (let 0 = 1) && true {} | ^^^^^^^^^ -error: `let` expressions are not supported here - --> $DIR/disallowed-positions.rs:41:17 +error: expected expression, found `let` statement + --> $DIR/disallowed-positions.rs:38:17 | LL | if true && (let 0 = 1) {} | ^^^^^^^^^ | = note: only supported directly in conditions of `if` and `while` expressions note: `let`s wrapped in parentheses are not supported in a context with let chains - --> $DIR/disallowed-positions.rs:41:17 + --> $DIR/disallowed-positions.rs:38:17 | LL | if true && (let 0 = 1) {} | ^^^^^^^^^ -error: `let` expressions are not supported here - --> $DIR/disallowed-positions.rs:45:9 +error: expected expression, found `let` statement + --> $DIR/disallowed-positions.rs:41:9 | LL | if (let 0 = 1) && (let 0 = 1) {} | ^^^^^^^^^ | = note: only supported directly in conditions of `if` and `while` expressions note: `let`s wrapped in parentheses are not supported in a context with let chains - --> $DIR/disallowed-positions.rs:45:9 + --> $DIR/disallowed-positions.rs:41:9 | LL | if (let 0 = 1) && (let 0 = 1) {} | ^^^^^^^^^ -error: `let` expressions are not supported here - --> $DIR/disallowed-positions.rs:45:24 +error: expected expression, found `let` statement + --> $DIR/disallowed-positions.rs:41:24 | LL | if (let 0 = 1) && (let 0 = 1) {} | ^^^^^^^^^ | = note: only supported directly in conditions of `if` and `while` expressions note: `let`s wrapped in parentheses are not supported in a context with let chains - --> $DIR/disallowed-positions.rs:45:24 + --> $DIR/disallowed-positions.rs:41:24 | LL | if (let 0 = 1) && (let 0 = 1) {} | ^^^^^^^^^ -error: `let` expressions are not supported here - --> $DIR/disallowed-positions.rs:51:35 +error: expected expression, found `let` statement + --> $DIR/disallowed-positions.rs:45:35 | LL | if let 0 = 1 && let 1 = 2 && (let 2 = 3 && let 3 = 4 && let 4 = 5) {} | ^^^^^^^^^ | = note: only supported directly in conditions of `if` and `while` expressions note: `let`s wrapped in parentheses are not supported in a context with let chains - --> $DIR/disallowed-positions.rs:51:35 + --> $DIR/disallowed-positions.rs:45:35 | LL | if let 0 = 1 && let 1 = 2 && (let 2 = 3 && let 3 = 4 && let 4 = 5) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: `let` expressions are not supported here - --> $DIR/disallowed-positions.rs:51:48 +error: expected expression, found `let` statement + --> $DIR/disallowed-positions.rs:45:48 | LL | if let 0 = 1 && let 1 = 2 && (let 2 = 3 && let 3 = 4 && let 4 = 5) {} | ^^^^^^^^^ | = note: only supported directly in conditions of `if` and `while` expressions note: `let`s wrapped in parentheses are not supported in a context with let chains - --> $DIR/disallowed-positions.rs:51:35 + --> $DIR/disallowed-positions.rs:45:35 | LL | if let 0 = 1 && let 1 = 2 && (let 2 = 3 && let 3 = 4 && let 4 = 5) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: `let` expressions are not supported here - --> $DIR/disallowed-positions.rs:51:61 +error: expected expression, found `let` statement + --> $DIR/disallowed-positions.rs:45:61 | LL | if let 0 = 1 && let 1 = 2 && (let 2 = 3 && let 3 = 4 && let 4 = 5) {} | ^^^^^^^^^ | = note: only supported directly in conditions of `if` and `while` expressions note: `let`s wrapped in parentheses are not supported in a context with let chains - --> $DIR/disallowed-positions.rs:51:35 + --> $DIR/disallowed-positions.rs:45:35 | LL | if let 0 = 1 && let 1 = 2 && (let 2 = 3 && let 3 = 4 && let 4 = 5) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: `let` expressions are not supported here - --> $DIR/disallowed-positions.rs:61:12 +error: expected expression, found `let` statement + --> $DIR/disallowed-positions.rs:52:12 | LL | while (let 0 = 1) {} | ^^^^^^^^^ | = note: only supported directly in conditions of `if` and `while` expressions note: `let`s wrapped in parentheses are not supported in a context with let chains - --> $DIR/disallowed-positions.rs:61:12 + --> $DIR/disallowed-positions.rs:52:12 | LL | while (let 0 = 1) {} | ^^^^^^^^^ -error: `let` expressions are not supported here - --> $DIR/disallowed-positions.rs:65:14 +error: expected expression, found `let` statement + --> $DIR/disallowed-positions.rs:55:14 | LL | while (((let 0 = 1))) {} | ^^^^^^^^^ | = note: only supported directly in conditions of `if` and `while` expressions note: `let`s wrapped in parentheses are not supported in a context with let chains - --> $DIR/disallowed-positions.rs:65:14 + --> $DIR/disallowed-positions.rs:55:14 | LL | while (((let 0 = 1))) {} | ^^^^^^^^^ -error: `let` expressions are not supported here - --> $DIR/disallowed-positions.rs:69:12 +error: expected expression, found `let` statement + --> $DIR/disallowed-positions.rs:58:12 | LL | while (let 0 = 1) && true {} | ^^^^^^^^^ | = note: only supported directly in conditions of `if` and `while` expressions note: `let`s wrapped in parentheses are not supported in a context with let chains - --> $DIR/disallowed-positions.rs:69:12 + --> $DIR/disallowed-positions.rs:58:12 | LL | while (let 0 = 1) && true {} | ^^^^^^^^^ -error: `let` expressions are not supported here - --> $DIR/disallowed-positions.rs:73:20 +error: expected expression, found `let` statement + --> $DIR/disallowed-positions.rs:61:20 | LL | while true && (let 0 = 1) {} | ^^^^^^^^^ | = note: only supported directly in conditions of `if` and `while` expressions note: `let`s wrapped in parentheses are not supported in a context with let chains - --> $DIR/disallowed-positions.rs:73:20 + --> $DIR/disallowed-positions.rs:61:20 | LL | while true && (let 0 = 1) {} | ^^^^^^^^^ -error: `let` expressions are not supported here - --> $DIR/disallowed-positions.rs:77:12 +error: expected expression, found `let` statement + --> $DIR/disallowed-positions.rs:64:12 | LL | while (let 0 = 1) && (let 0 = 1) {} | ^^^^^^^^^ | = note: only supported directly in conditions of `if` and `while` expressions note: `let`s wrapped in parentheses are not supported in a context with let chains - --> $DIR/disallowed-positions.rs:77:12 + --> $DIR/disallowed-positions.rs:64:12 | LL | while (let 0 = 1) && (let 0 = 1) {} | ^^^^^^^^^ -error: `let` expressions are not supported here - --> $DIR/disallowed-positions.rs:77:27 +error: expected expression, found `let` statement + --> $DIR/disallowed-positions.rs:64:27 | LL | while (let 0 = 1) && (let 0 = 1) {} | ^^^^^^^^^ | = note: only supported directly in conditions of `if` and `while` expressions note: `let`s wrapped in parentheses are not supported in a context with let chains - --> $DIR/disallowed-positions.rs:77:27 + --> $DIR/disallowed-positions.rs:64:27 | LL | while (let 0 = 1) && (let 0 = 1) {} | ^^^^^^^^^ -error: `let` expressions are not supported here - --> $DIR/disallowed-positions.rs:83:38 +error: expected expression, found `let` statement + --> $DIR/disallowed-positions.rs:68:38 | LL | while let 0 = 1 && let 1 = 2 && (let 2 = 3 && let 3 = 4 && let 4 = 5) {} | ^^^^^^^^^ | = note: only supported directly in conditions of `if` and `while` expressions note: `let`s wrapped in parentheses are not supported in a context with let chains - --> $DIR/disallowed-positions.rs:83:38 + --> $DIR/disallowed-positions.rs:68:38 | LL | while let 0 = 1 && let 1 = 2 && (let 2 = 3 && let 3 = 4 && let 4 = 5) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: `let` expressions are not supported here - --> $DIR/disallowed-positions.rs:83:51 +error: expected expression, found `let` statement + --> $DIR/disallowed-positions.rs:68:51 | LL | while let 0 = 1 && let 1 = 2 && (let 2 = 3 && let 3 = 4 && let 4 = 5) {} | ^^^^^^^^^ | = note: only supported directly in conditions of `if` and `while` expressions note: `let`s wrapped in parentheses are not supported in a context with let chains - --> $DIR/disallowed-positions.rs:83:38 + --> $DIR/disallowed-positions.rs:68:38 | LL | while let 0 = 1 && let 1 = 2 && (let 2 = 3 && let 3 = 4 && let 4 = 5) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: `let` expressions are not supported here - --> $DIR/disallowed-positions.rs:83:64 +error: expected expression, found `let` statement + --> $DIR/disallowed-positions.rs:68:64 | LL | while let 0 = 1 && let 1 = 2 && (let 2 = 3 && let 3 = 4 && let 4 = 5) {} | ^^^^^^^^^ | = note: only supported directly in conditions of `if` and `while` expressions note: `let`s wrapped in parentheses are not supported in a context with let chains - --> $DIR/disallowed-positions.rs:83:38 + --> $DIR/disallowed-positions.rs:68:38 | LL | while let 0 = 1 && let 1 = 2 && (let 2 = 3 && let 3 = 4 && let 4 = 5) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: `let` expressions are not supported here - --> $DIR/disallowed-positions.rs:99:16 - | -LL | use_expr!((let 0 = 1 && 0 == 0)); - | ^^^^^^^^^ - | - = note: only supported directly in conditions of `if` and `while` expressions -note: `let`s wrapped in parentheses are not supported in a context with let chains - --> $DIR/disallowed-positions.rs:99:16 - | -LL | use_expr!((let 0 = 1 && 0 == 0)); - | ^^^^^^^^^^^^^^^^^^^ - -error: `let` expressions are not supported here - --> $DIR/disallowed-positions.rs:99:16 - | -LL | use_expr!((let 0 = 1 && 0 == 0)); - | ^^^^^^^^^ - | - = note: only supported directly in conditions of `if` and `while` expressions -note: `let`s wrapped in parentheses are not supported in a context with let chains - --> $DIR/disallowed-positions.rs:99:16 - | -LL | use_expr!((let 0 = 1 && 0 == 0)); - | ^^^^^^^^^^^^^^^^^^^ - -error: `let` expressions are not supported here - --> $DIR/disallowed-positions.rs:103:16 - | -LL | use_expr!((let 0 = 1)); - | ^^^^^^^^^ - | - = note: only supported directly in conditions of `if` and `while` expressions -note: `let`s wrapped in parentheses are not supported in a context with let chains - --> $DIR/disallowed-positions.rs:103:16 - | -LL | use_expr!((let 0 = 1)); - | ^^^^^^^^^ - -error: `let` expressions are not supported here - --> $DIR/disallowed-positions.rs:103:16 - | -LL | use_expr!((let 0 = 1)); - | ^^^^^^^^^ - | - = note: only supported directly in conditions of `if` and `while` expressions -note: `let`s wrapped in parentheses are not supported in a context with let chains - --> $DIR/disallowed-positions.rs:103:16 - | -LL | use_expr!((let 0 = 1)); - | ^^^^^^^^^ - -error: `let` expressions are not supported here - --> $DIR/disallowed-positions.rs:110:9 +error: expected expression, found `let` statement + --> $DIR/disallowed-positions.rs:88:9 | LL | if &let 0 = 0 {} | ^^^^^^^^^ | = note: only supported directly in conditions of `if` and `while` expressions -error: `let` expressions are not supported here - --> $DIR/disallowed-positions.rs:115:9 +error: expected expression, found `let` statement + --> $DIR/disallowed-positions.rs:91:9 | LL | if !let 0 = 0 {} | ^^^^^^^^^ | = note: only supported directly in conditions of `if` and `while` expressions -error: `let` expressions are not supported here - --> $DIR/disallowed-positions.rs:118:9 +error: expected expression, found `let` statement + --> $DIR/disallowed-positions.rs:93:9 | LL | if *let 0 = 0 {} | ^^^^^^^^^ | = note: only supported directly in conditions of `if` and `while` expressions -error: `let` expressions are not supported here - --> $DIR/disallowed-positions.rs:122:9 +error: expected expression, found `let` statement + --> $DIR/disallowed-positions.rs:95:9 | LL | if -let 0 = 0 {} | ^^^^^^^^^ | = note: only supported directly in conditions of `if` and `while` expressions -error: `let` expressions are not supported here - --> $DIR/disallowed-positions.rs:132:9 +error: expected expression, found `let` statement + --> $DIR/disallowed-positions.rs:103:9 | LL | if (let 0 = 0)? {} | ^^^^^^^^^ | = note: only supported directly in conditions of `if` and `while` expressions -note: `let`s wrapped in parentheses are not supported in a context with let chains - --> $DIR/disallowed-positions.rs:132:9 - | -LL | if (let 0 = 0)? {} - | ^^^^^^^^^ -error: `let` expressions are not supported here - --> $DIR/disallowed-positions.rs:138:16 +error: expected expression, found `let` statement + --> $DIR/disallowed-positions.rs:106:16 | LL | if true || let 0 = 0 {} | ^^^^^^^^^ | = note: only supported directly in conditions of `if` and `while` expressions note: `||` operators are not supported in let chain expressions - --> $DIR/disallowed-positions.rs:138:13 + --> $DIR/disallowed-positions.rs:106:13 | LL | if true || let 0 = 0 {} | ^^ -error: `let` expressions are not supported here - --> $DIR/disallowed-positions.rs:141:17 +error: expected expression, found `let` statement + --> $DIR/disallowed-positions.rs:108:17 | LL | if (true || let 0 = 0) {} | ^^^^^^^^^ | = note: only supported directly in conditions of `if` and `while` expressions -note: `||` operators are not supported in let chain expressions - --> $DIR/disallowed-positions.rs:141:14 - | -LL | if (true || let 0 = 0) {} - | ^^ -error: `let` expressions are not supported here - --> $DIR/disallowed-positions.rs:144:25 +error: expected expression, found `let` statement + --> $DIR/disallowed-positions.rs:110:25 | LL | if true && (true || let 0 = 0) {} | ^^^^^^^^^ | = note: only supported directly in conditions of `if` and `while` expressions -note: `||` operators are not supported in let chain expressions - --> $DIR/disallowed-positions.rs:144:22 - | -LL | if true && (true || let 0 = 0) {} - | ^^ -error: `let` expressions are not supported here - --> $DIR/disallowed-positions.rs:147:25 +error: expected expression, found `let` statement + --> $DIR/disallowed-positions.rs:112:25 | LL | if true || (true && let 0 = 0) {} | ^^^^^^^^^ | = note: only supported directly in conditions of `if` and `while` expressions -note: `let`s wrapped in parentheses are not supported in a context with let chains - --> $DIR/disallowed-positions.rs:147:17 - | -LL | if true || (true && let 0 = 0) {} - | ^^^^^^^^^^^^^^^^^ -error: `let` expressions are not supported here - --> $DIR/disallowed-positions.rs:152:12 +error: expected expression, found `let` statement + --> $DIR/disallowed-positions.rs:116:12 | LL | if x = let 0 = 0 {} - | ^^^^^^^^^ + | ^^^ | = note: only supported directly in conditions of `if` and `while` expressions -error: `let` expressions are not supported here - --> $DIR/disallowed-positions.rs:157:15 +error: expected expression, found `let` statement + --> $DIR/disallowed-positions.rs:119:15 | LL | if true..(let 0 = 0) {} | ^^^^^^^^^ | = note: only supported directly in conditions of `if` and `while` expressions -note: `let`s wrapped in parentheses are not supported in a context with let chains - --> $DIR/disallowed-positions.rs:157:15 - | -LL | if true..(let 0 = 0) {} - | ^^^^^^^^^ -error: `let` expressions are not supported here - --> $DIR/disallowed-positions.rs:161:11 +error: expected expression, found `let` statement + --> $DIR/disallowed-positions.rs:122:11 | LL | if ..(let 0 = 0) {} | ^^^^^^^^^ | = note: only supported directly in conditions of `if` and `while` expressions -note: `let`s wrapped in parentheses are not supported in a context with let chains - --> $DIR/disallowed-positions.rs:161:11 - | -LL | if ..(let 0 = 0) {} - | ^^^^^^^^^ -error: `let` expressions are not supported here - --> $DIR/disallowed-positions.rs:165:9 +error: expected expression, found `let` statement + --> $DIR/disallowed-positions.rs:124:9 | LL | if (let 0 = 0).. {} | ^^^^^^^^^ | = note: only supported directly in conditions of `if` and `while` expressions -note: `let`s wrapped in parentheses are not supported in a context with let chains - --> $DIR/disallowed-positions.rs:165:9 - | -LL | if (let 0 = 0).. {} - | ^^^^^^^^^ -error: `let` expressions are not supported here - --> $DIR/disallowed-positions.rs:171:8 +error: expected expression, found `let` statement + --> $DIR/disallowed-positions.rs:128:8 | LL | if let Range { start: _, end: _ } = true..true && false {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: only supported directly in conditions of `if` and `while` expressions -error: `let` expressions are not supported here - --> $DIR/disallowed-positions.rs:175:8 +error: expected expression, found `let` statement + --> $DIR/disallowed-positions.rs:131:8 | LL | if let Range { start: _, end: _ } = true..true || false {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: only supported directly in conditions of `if` and `while` expressions -error: `let` expressions are not supported here - --> $DIR/disallowed-positions.rs:182:8 +error: expected expression, found `let` statement + --> $DIR/disallowed-positions.rs:137:8 | LL | if let Range { start: F, end } = F..|| true {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: only supported directly in conditions of `if` and `while` expressions -error: `let` expressions are not supported here - --> $DIR/disallowed-positions.rs:190:8 +error: expected expression, found `let` statement + --> $DIR/disallowed-positions.rs:143:8 | LL | if let Range { start: true, end } = t..&&false {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: only supported directly in conditions of `if` and `while` expressions -error: `let` expressions are not supported here - --> $DIR/disallowed-positions.rs:196:19 +error: expected expression, found `let` statement + --> $DIR/disallowed-positions.rs:147:19 | LL | if let true = let true = true {} - | ^^^^^^^^^^^^^^^ + | ^^^ | = note: only supported directly in conditions of `if` and `while` expressions -error: `let` expressions are not supported here - --> $DIR/disallowed-positions.rs:202:12 +error: expected expression, found `let` statement + --> $DIR/disallowed-positions.rs:152:12 | LL | while &let 0 = 0 {} | ^^^^^^^^^ | = note: only supported directly in conditions of `if` and `while` expressions -error: `let` expressions are not supported here - --> $DIR/disallowed-positions.rs:207:12 +error: expected expression, found `let` statement + --> $DIR/disallowed-positions.rs:155:12 | LL | while !let 0 = 0 {} | ^^^^^^^^^ | = note: only supported directly in conditions of `if` and `while` expressions -error: `let` expressions are not supported here - --> $DIR/disallowed-positions.rs:210:12 +error: expected expression, found `let` statement + --> $DIR/disallowed-positions.rs:157:12 | LL | while *let 0 = 0 {} | ^^^^^^^^^ | = note: only supported directly in conditions of `if` and `while` expressions -error: `let` expressions are not supported here - --> $DIR/disallowed-positions.rs:214:12 +error: expected expression, found `let` statement + --> $DIR/disallowed-positions.rs:159:12 | LL | while -let 0 = 0 {} | ^^^^^^^^^ | = note: only supported directly in conditions of `if` and `while` expressions -error: `let` expressions are not supported here - --> $DIR/disallowed-positions.rs:224:12 +error: expected expression, found `let` statement + --> $DIR/disallowed-positions.rs:167:12 | LL | while (let 0 = 0)? {} | ^^^^^^^^^ | = note: only supported directly in conditions of `if` and `while` expressions -note: `let`s wrapped in parentheses are not supported in a context with let chains - --> $DIR/disallowed-positions.rs:224:12 - | -LL | while (let 0 = 0)? {} - | ^^^^^^^^^ -error: `let` expressions are not supported here - --> $DIR/disallowed-positions.rs:230:19 +error: expected expression, found `let` statement + --> $DIR/disallowed-positions.rs:170:19 | LL | while true || let 0 = 0 {} | ^^^^^^^^^ | = note: only supported directly in conditions of `if` and `while` expressions note: `||` operators are not supported in let chain expressions - --> $DIR/disallowed-positions.rs:230:16 + --> $DIR/disallowed-positions.rs:170:16 | LL | while true || let 0 = 0 {} | ^^ -error: `let` expressions are not supported here - --> $DIR/disallowed-positions.rs:233:20 +error: expected expression, found `let` statement + --> $DIR/disallowed-positions.rs:172:20 | LL | while (true || let 0 = 0) {} | ^^^^^^^^^ | = note: only supported directly in conditions of `if` and `while` expressions -note: `||` operators are not supported in let chain expressions - --> $DIR/disallowed-positions.rs:233:17 - | -LL | while (true || let 0 = 0) {} - | ^^ -error: `let` expressions are not supported here - --> $DIR/disallowed-positions.rs:236:28 +error: expected expression, found `let` statement + --> $DIR/disallowed-positions.rs:174:28 | LL | while true && (true || let 0 = 0) {} | ^^^^^^^^^ | = note: only supported directly in conditions of `if` and `while` expressions -note: `||` operators are not supported in let chain expressions - --> $DIR/disallowed-positions.rs:236:25 - | -LL | while true && (true || let 0 = 0) {} - | ^^ -error: `let` expressions are not supported here - --> $DIR/disallowed-positions.rs:239:28 +error: expected expression, found `let` statement + --> $DIR/disallowed-positions.rs:176:28 | LL | while true || (true && let 0 = 0) {} | ^^^^^^^^^ | = note: only supported directly in conditions of `if` and `while` expressions -note: `let`s wrapped in parentheses are not supported in a context with let chains - --> $DIR/disallowed-positions.rs:239:20 - | -LL | while true || (true && let 0 = 0) {} - | ^^^^^^^^^^^^^^^^^ -error: `let` expressions are not supported here - --> $DIR/disallowed-positions.rs:244:15 +error: expected expression, found `let` statement + --> $DIR/disallowed-positions.rs:180:15 | LL | while x = let 0 = 0 {} - | ^^^^^^^^^ + | ^^^ | = note: only supported directly in conditions of `if` and `while` expressions -error: `let` expressions are not supported here - --> $DIR/disallowed-positions.rs:249:18 +error: expected expression, found `let` statement + --> $DIR/disallowed-positions.rs:183:18 | LL | while true..(let 0 = 0) {} | ^^^^^^^^^ | = note: only supported directly in conditions of `if` and `while` expressions -note: `let`s wrapped in parentheses are not supported in a context with let chains - --> $DIR/disallowed-positions.rs:249:18 - | -LL | while true..(let 0 = 0) {} - | ^^^^^^^^^ -error: `let` expressions are not supported here - --> $DIR/disallowed-positions.rs:253:14 +error: expected expression, found `let` statement + --> $DIR/disallowed-positions.rs:186:14 | LL | while ..(let 0 = 0) {} | ^^^^^^^^^ | = note: only supported directly in conditions of `if` and `while` expressions -note: `let`s wrapped in parentheses are not supported in a context with let chains - --> $DIR/disallowed-positions.rs:253:14 - | -LL | while ..(let 0 = 0) {} - | ^^^^^^^^^ -error: `let` expressions are not supported here - --> $DIR/disallowed-positions.rs:257:12 +error: expected expression, found `let` statement + --> $DIR/disallowed-positions.rs:188:12 | LL | while (let 0 = 0).. {} | ^^^^^^^^^ | = note: only supported directly in conditions of `if` and `while` expressions -note: `let`s wrapped in parentheses are not supported in a context with let chains - --> $DIR/disallowed-positions.rs:257:12 - | -LL | while (let 0 = 0).. {} - | ^^^^^^^^^ -error: `let` expressions are not supported here - --> $DIR/disallowed-positions.rs:263:11 +error: expected expression, found `let` statement + --> $DIR/disallowed-positions.rs:192:11 | LL | while let Range { start: _, end: _ } = true..true && false {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: only supported directly in conditions of `if` and `while` expressions -error: `let` expressions are not supported here - --> $DIR/disallowed-positions.rs:267:11 +error: expected expression, found `let` statement + --> $DIR/disallowed-positions.rs:195:11 | LL | while let Range { start: _, end: _ } = true..true || false {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: only supported directly in conditions of `if` and `while` expressions -error: `let` expressions are not supported here - --> $DIR/disallowed-positions.rs:274:11 +error: expected expression, found `let` statement + --> $DIR/disallowed-positions.rs:201:11 | LL | while let Range { start: F, end } = F..|| true {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: only supported directly in conditions of `if` and `while` expressions -error: `let` expressions are not supported here - --> $DIR/disallowed-positions.rs:282:11 +error: expected expression, found `let` statement + --> $DIR/disallowed-positions.rs:207:11 | LL | while let Range { start: true, end } = t..&&false {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: only supported directly in conditions of `if` and `while` expressions -error: `let` expressions are not supported here - --> $DIR/disallowed-positions.rs:288:22 +error: expected expression, found `let` statement + --> $DIR/disallowed-positions.rs:211:22 | LL | while let true = let true = true {} - | ^^^^^^^^^^^^^^^ + | ^^^ | = note: only supported directly in conditions of `if` and `while` expressions -error: `let` expressions are not supported here - --> $DIR/disallowed-positions.rs:304:6 +error: expected expression, found `let` statement + --> $DIR/disallowed-positions.rs:226:6 | LL | &let 0 = 0; - | ^^^^^^^^^ + | ^^^ | = note: only supported directly in conditions of `if` and `while` expressions -error: `let` expressions are not supported here - --> $DIR/disallowed-positions.rs:308:6 +error: expected expression, found `let` statement + --> $DIR/disallowed-positions.rs:229:6 | LL | !let 0 = 0; - | ^^^^^^^^^ + | ^^^ | = note: only supported directly in conditions of `if` and `while` expressions -error: `let` expressions are not supported here - --> $DIR/disallowed-positions.rs:311:6 +error: expected expression, found `let` statement + --> $DIR/disallowed-positions.rs:231:6 | LL | *let 0 = 0; - | ^^^^^^^^^ + | ^^^ | = note: only supported directly in conditions of `if` and `while` expressions -error: `let` expressions are not supported here - --> $DIR/disallowed-positions.rs:315:6 +error: expected expression, found `let` statement + --> $DIR/disallowed-positions.rs:233:6 | LL | -let 0 = 0; - | ^^^^^^^^^ + | ^^^ | = note: only supported directly in conditions of `if` and `while` expressions -error: `let` expressions are not supported here - --> $DIR/disallowed-positions.rs:325:6 +error: expected expression, found `let` statement + --> $DIR/disallowed-positions.rs:241:6 | LL | (let 0 = 0)?; - | ^^^^^^^^^ + | ^^^ | = note: only supported directly in conditions of `if` and `while` expressions -note: `let`s wrapped in parentheses are not supported in a context with let chains - --> $DIR/disallowed-positions.rs:325:6 - | -LL | (let 0 = 0)?; - | ^^^^^^^^^ -error: `let` expressions are not supported here - --> $DIR/disallowed-positions.rs:331:13 +error: expected expression, found `let` statement + --> $DIR/disallowed-positions.rs:244:13 | LL | true || let 0 = 0; - | ^^^^^^^^^ + | ^^^ | = note: only supported directly in conditions of `if` and `while` expressions -note: `||` operators are not supported in let chain expressions - --> $DIR/disallowed-positions.rs:331:10 - | -LL | true || let 0 = 0; - | ^^ -error: `let` expressions are not supported here - --> $DIR/disallowed-positions.rs:334:14 +error: expected expression, found `let` statement + --> $DIR/disallowed-positions.rs:246:14 | LL | (true || let 0 = 0); - | ^^^^^^^^^ + | ^^^ | = note: only supported directly in conditions of `if` and `while` expressions -note: `||` operators are not supported in let chain expressions - --> $DIR/disallowed-positions.rs:334:11 - | -LL | (true || let 0 = 0); - | ^^ -error: `let` expressions are not supported here - --> $DIR/disallowed-positions.rs:337:22 +error: expected expression, found `let` statement + --> $DIR/disallowed-positions.rs:248:22 | LL | true && (true || let 0 = 0); - | ^^^^^^^^^ + | ^^^ | = note: only supported directly in conditions of `if` and `while` expressions -note: `||` operators are not supported in let chain expressions - --> $DIR/disallowed-positions.rs:337:19 - | -LL | true && (true || let 0 = 0); - | ^^ -error: `let` expressions are not supported here - --> $DIR/disallowed-positions.rs:342:9 +error: expected expression, found `let` statement + --> $DIR/disallowed-positions.rs:252:9 | LL | x = let 0 = 0; - | ^^^^^^^^^ + | ^^^ | = note: only supported directly in conditions of `if` and `while` expressions -error: `let` expressions are not supported here - --> $DIR/disallowed-positions.rs:346:12 +error: expected expression, found `let` statement + --> $DIR/disallowed-positions.rs:255:12 | LL | true..(let 0 = 0); - | ^^^^^^^^^ + | ^^^ | = note: only supported directly in conditions of `if` and `while` expressions -note: `let`s wrapped in parentheses are not supported in a context with let chains - --> $DIR/disallowed-positions.rs:346:12 - | -LL | true..(let 0 = 0); - | ^^^^^^^^^ -error: `let` expressions are not supported here - --> $DIR/disallowed-positions.rs:349:8 +error: expected expression, found `let` statement + --> $DIR/disallowed-positions.rs:257:8 | LL | ..(let 0 = 0); - | ^^^^^^^^^ + | ^^^ | = note: only supported directly in conditions of `if` and `while` expressions -note: `let`s wrapped in parentheses are not supported in a context with let chains - --> $DIR/disallowed-positions.rs:349:8 - | -LL | ..(let 0 = 0); - | ^^^^^^^^^ -error: `let` expressions are not supported here - --> $DIR/disallowed-positions.rs:352:6 +error: expected expression, found `let` statement + --> $DIR/disallowed-positions.rs:259:6 | LL | (let 0 = 0)..; - | ^^^^^^^^^ + | ^^^ | = note: only supported directly in conditions of `if` and `while` expressions -note: `let`s wrapped in parentheses are not supported in a context with let chains - --> $DIR/disallowed-positions.rs:352:6 - | -LL | (let 0 = 0)..; - | ^^^^^^^^^ -error: `let` expressions are not supported here - --> $DIR/disallowed-positions.rs:356:6 +error: expected expression, found `let` statement + --> $DIR/disallowed-positions.rs:262:6 | LL | (let Range { start: _, end: _ } = true..true || false); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^ | = note: only supported directly in conditions of `if` and `while` expressions -error: `let` expressions are not supported here - --> $DIR/disallowed-positions.rs:361:6 +error: expected expression, found `let` statement + --> $DIR/disallowed-positions.rs:266:6 | LL | (let true = let true = true); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^ | = note: only supported directly in conditions of `if` and `while` expressions -note: `let`s wrapped in parentheses are not supported in a context with let chains - --> $DIR/disallowed-positions.rs:361:6 + +error: expected expression, found `let` statement + --> $DIR/disallowed-positions.rs:266:17 | LL | (let true = let true = true); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^ + | + = note: only supported directly in conditions of `if` and `while` expressions + +error: expected expression, found `let` statement + --> $DIR/disallowed-positions.rs:272:25 + | +LL | let x = true && let y = 1; + | ^^^ + | + = note: only supported directly in conditions of `if` and `while` expressions + +error: expected expression, found `let` statement + --> $DIR/disallowed-positions.rs:278:19 + | +LL | [1, 2, 3][let _ = ()] + | ^^^ + | + = note: only supported directly in conditions of `if` and `while` expressions -error: `let` expressions are not supported here - --> $DIR/disallowed-positions.rs:379:6 +error: expected expression, found `let` statement + --> $DIR/disallowed-positions.rs:283:6 | LL | &let 0 = 0 - | ^^^^^^^^^ + | ^^^ | = note: only supported directly in conditions of `if` and `while` expressions -error: `let` expressions are not supported here - --> $DIR/disallowed-positions.rs:391:17 +error: expected expression, found `let` statement + --> $DIR/disallowed-positions.rs:293:17 | LL | true && let 1 = 1 - | ^^^^^^^^^ + | ^^^ | = note: only supported directly in conditions of `if` and `while` expressions -error: `let` expressions are not supported here - --> $DIR/disallowed-positions.rs:397:17 +error: expected expression, found `let` statement + --> $DIR/disallowed-positions.rs:298:17 | LL | true && let 1 = 1 - | ^^^^^^^^^ + | ^^^ | = note: only supported directly in conditions of `if` and `while` expressions -error: `let` expressions are not supported here - --> $DIR/disallowed-positions.rs:403:17 +error: expected expression, found `let` statement + --> $DIR/disallowed-positions.rs:303:17 | LL | true && let 1 = 1 - | ^^^^^^^^^ + | ^^^ | = note: only supported directly in conditions of `if` and `while` expressions -error: `let` expressions are not supported here - --> $DIR/disallowed-positions.rs:415:17 +error: expected expression, found `let` statement + --> $DIR/disallowed-positions.rs:314:17 | LL | true && let 1 = 1 - | ^^^^^^^^^ + | ^^^ | = note: only supported directly in conditions of `if` and `while` expressions -error: `let` expressions are not supported here - --> $DIR/disallowed-positions.rs:425:9 +error: expressions must be enclosed in braces to be used as const generic arguments + --> $DIR/disallowed-positions.rs:314:9 + | +LL | true && let 1 = 1 + | ^^^^^^^^^^^^^^^^^ + | +help: enclose the `const` expression in braces + | +LL | { true && let 1 = 1 } + | + + + +error: expected expression, found `let` statement + --> $DIR/disallowed-positions.rs:323:9 | LL | if (let Some(a) = opt && true) { | ^^^^^^^^^^^^^^^^^ | = note: only supported directly in conditions of `if` and `while` expressions note: `let`s wrapped in parentheses are not supported in a context with let chains - --> $DIR/disallowed-positions.rs:425:9 + --> $DIR/disallowed-positions.rs:323:9 | LL | if (let Some(a) = opt && true) { | ^^^^^^^^^^^^^^^^^^^^^^^^^ -error: `let` expressions are not supported here - --> $DIR/disallowed-positions.rs:430:9 +error: expected expression, found `let` statement + --> $DIR/disallowed-positions.rs:327:9 | LL | if (let Some(a) = opt) && true { | ^^^^^^^^^^^^^^^^^ | = note: only supported directly in conditions of `if` and `while` expressions note: `let`s wrapped in parentheses are not supported in a context with let chains - --> $DIR/disallowed-positions.rs:430:9 + --> $DIR/disallowed-positions.rs:327:9 | LL | if (let Some(a) = opt) && true { | ^^^^^^^^^^^^^^^^^ -error: `let` expressions are not supported here - --> $DIR/disallowed-positions.rs:434:9 +error: expected expression, found `let` statement + --> $DIR/disallowed-positions.rs:330:9 | LL | if (let Some(a) = opt) && (let Some(b) = a) { | ^^^^^^^^^^^^^^^^^ | = note: only supported directly in conditions of `if` and `while` expressions note: `let`s wrapped in parentheses are not supported in a context with let chains - --> $DIR/disallowed-positions.rs:434:9 + --> $DIR/disallowed-positions.rs:330:9 | LL | if (let Some(a) = opt) && (let Some(b) = a) { | ^^^^^^^^^^^^^^^^^ -error: `let` expressions are not supported here - --> $DIR/disallowed-positions.rs:434:32 +error: expected expression, found `let` statement + --> $DIR/disallowed-positions.rs:330:32 | LL | if (let Some(a) = opt) && (let Some(b) = a) { | ^^^^^^^^^^^^^^^ | = note: only supported directly in conditions of `if` and `while` expressions note: `let`s wrapped in parentheses are not supported in a context with let chains - --> $DIR/disallowed-positions.rs:434:32 + --> $DIR/disallowed-positions.rs:330:32 | LL | if (let Some(a) = opt) && (let Some(b) = a) { | ^^^^^^^^^^^^^^^ -error: `let` expressions are not supported here - --> $DIR/disallowed-positions.rs:443:9 +error: expected expression, found `let` statement + --> $DIR/disallowed-positions.rs:337:9 | LL | if (let Some(a) = opt && (let Some(b) = a)) && b == 1 { | ^^^^^^^^^^^^^^^^^ | = note: only supported directly in conditions of `if` and `while` expressions note: `let`s wrapped in parentheses are not supported in a context with let chains - --> $DIR/disallowed-positions.rs:443:9 + --> $DIR/disallowed-positions.rs:337:9 | LL | if (let Some(a) = opt && (let Some(b) = a)) && b == 1 { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: `let` expressions are not supported here - --> $DIR/disallowed-positions.rs:443:31 +error: expected expression, found `let` statement + --> $DIR/disallowed-positions.rs:337:31 | LL | if (let Some(a) = opt && (let Some(b) = a)) && b == 1 { | ^^^^^^^^^^^^^^^ | = note: only supported directly in conditions of `if` and `while` expressions note: `let`s wrapped in parentheses are not supported in a context with let chains - --> $DIR/disallowed-positions.rs:443:31 + --> $DIR/disallowed-positions.rs:337:31 | LL | if (let Some(a) = opt && (let Some(b) = a)) && b == 1 { | ^^^^^^^^^^^^^^^ -error: `let` expressions are not supported here - --> $DIR/disallowed-positions.rs:449:9 +error: expected expression, found `let` statement + --> $DIR/disallowed-positions.rs:341:9 | LL | if (let Some(a) = opt && (let Some(b) = a)) && true { | ^^^^^^^^^^^^^^^^^ | = note: only supported directly in conditions of `if` and `while` expressions note: `let`s wrapped in parentheses are not supported in a context with let chains - --> $DIR/disallowed-positions.rs:449:9 + --> $DIR/disallowed-positions.rs:341:9 | LL | if (let Some(a) = opt && (let Some(b) = a)) && true { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: `let` expressions are not supported here - --> $DIR/disallowed-positions.rs:449:31 +error: expected expression, found `let` statement + --> $DIR/disallowed-positions.rs:341:31 | LL | if (let Some(a) = opt && (let Some(b) = a)) && true { | ^^^^^^^^^^^^^^^ | = note: only supported directly in conditions of `if` and `while` expressions note: `let`s wrapped in parentheses are not supported in a context with let chains - --> $DIR/disallowed-positions.rs:449:31 + --> $DIR/disallowed-positions.rs:341:31 | LL | if (let Some(a) = opt && (let Some(b) = a)) && true { | ^^^^^^^^^^^^^^^ -error: `let` expressions are not supported here - --> $DIR/disallowed-positions.rs:455:9 +error: expected expression, found `let` statement + --> $DIR/disallowed-positions.rs:345:9 | LL | if (let Some(a) = opt && (true)) && true { | ^^^^^^^^^^^^^^^^^ | = note: only supported directly in conditions of `if` and `while` expressions note: `let`s wrapped in parentheses are not supported in a context with let chains - --> $DIR/disallowed-positions.rs:455:9 + --> $DIR/disallowed-positions.rs:345:9 | LL | if (let Some(a) = opt && (true)) && true { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error[E0308]: mismatched types - --> $DIR/disallowed-positions.rs:110:8 - | -LL | if &let 0 = 0 {} - | ^^^^^^^^^^ expected `bool`, found `&bool` - | -help: consider removing the borrow - | -LL - if &let 0 = 0 {} -LL + if let 0 = 0 {} - | - -error[E0614]: type `bool` cannot be dereferenced - --> $DIR/disallowed-positions.rs:118:8 +error: expected expression, found `let` statement + --> $DIR/disallowed-positions.rs:361:22 | -LL | if *let 0 = 0 {} - | ^^^^^^^^^^ - -error[E0600]: cannot apply unary operator `-` to type `bool` - --> $DIR/disallowed-positions.rs:122:8 +LL | let x = (true && let y = 1); + | ^^^ | -LL | if -let 0 = 0 {} - | ^^^^^^^^^^ cannot apply unary operator `-` + = note: only supported directly in conditions of `if` and `while` expressions -error[E0277]: the `?` operator can only be applied to values that implement `Try` - --> $DIR/disallowed-positions.rs:132:8 +error: expected expression, found `let` statement + --> $DIR/disallowed-positions.rs:366:20 | -LL | if (let 0 = 0)? {} - | ^^^^^^^^^^^^ the `?` operator cannot be applied to type `bool` +LL | ([1, 2, 3][let _ = ()]) + | ^^^ | - = help: the trait `Try` is not implemented for `bool` + = note: only supported directly in conditions of `if` and `while` expressions -error[E0277]: the `?` operator can only be used in a function that returns `Result` or `Option` (or another type that implements `FromResidual`) - --> $DIR/disallowed-positions.rs:132:19 +error: expected expression, found `let` statement + --> $DIR/disallowed-positions.rs:81:16 | -LL | fn nested_within_if_expr() { - | -------------------------- this function should return `Result` or `Option` to accept `?` -... -LL | if (let 0 = 0)? {} - | ^ cannot use the `?` operator in a function that returns `()` +LL | use_expr!((let 0 = 1 && 0 == 0)); + | ^^^ | - = help: the trait `FromResidual<_>` is not implemented for `()` + = note: only supported directly in conditions of `if` and `while` expressions -error[E0308]: mismatched types - --> $DIR/disallowed-positions.rs:152:8 - | -LL | if x = let 0 = 0 {} - | ^^^^^^^^^^^^^ expected `bool`, found `()` +error: expected expression, found `let` statement + --> $DIR/disallowed-positions.rs:83:16 | -help: you might have meant to compare for equality +LL | use_expr!((let 0 = 1)); + | ^^^ | -LL | if x == let 0 = 0 {} - | + + = note: only supported directly in conditions of `if` and `while` expressions error[E0308]: mismatched types - --> $DIR/disallowed-positions.rs:157:8 + --> $DIR/disallowed-positions.rs:119:8 | LL | if true..(let 0 = 0) {} | ^^^^^^^^^^^^^^^^^ expected `bool`, found `Range<bool>` @@ -1522,25 +876,7 @@ LL | if true..(let 0 = 0) {} found struct `std::ops::Range<bool>` error[E0308]: mismatched types - --> $DIR/disallowed-positions.rs:161:8 - | -LL | if ..(let 0 = 0) {} - | ^^^^^^^^^^^^^ expected `bool`, found `RangeTo<bool>` - | - = note: expected type `bool` - found struct `RangeTo<bool>` - -error[E0308]: mismatched types - --> $DIR/disallowed-positions.rs:165:8 - | -LL | if (let 0 = 0).. {} - | ^^^^^^^^^^^^^ expected `bool`, found `RangeFrom<bool>` - | - = note: expected type `bool` - found struct `RangeFrom<bool>` - -error[E0308]: mismatched types - --> $DIR/disallowed-positions.rs:171:12 + --> $DIR/disallowed-positions.rs:128:12 | LL | if let Range { start: _, end: _ } = true..true && false {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^ ---- this expression has type `bool` @@ -1551,16 +887,7 @@ LL | if let Range { start: _, end: _ } = true..true && false {} found struct `std::ops::Range<_>` error[E0308]: mismatched types - --> $DIR/disallowed-positions.rs:171:8 - | -LL | if let Range { start: _, end: _ } = true..true && false {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `bool`, found `Range<bool>` - | - = note: expected type `bool` - found struct `std::ops::Range<bool>` - -error[E0308]: mismatched types - --> $DIR/disallowed-positions.rs:175:12 + --> $DIR/disallowed-positions.rs:131:12 | LL | if let Range { start: _, end: _ } = true..true || false {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^ ---- this expression has type `bool` @@ -1571,16 +898,7 @@ LL | if let Range { start: _, end: _ } = true..true || false {} found struct `std::ops::Range<_>` error[E0308]: mismatched types - --> $DIR/disallowed-positions.rs:175:8 - | -LL | if let Range { start: _, end: _ } = true..true || false {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `bool`, found `Range<bool>` - | - = note: expected type `bool` - found struct `std::ops::Range<bool>` - -error[E0308]: mismatched types - --> $DIR/disallowed-positions.rs:182:12 + --> $DIR/disallowed-positions.rs:137:12 | LL | if let Range { start: F, end } = F..|| true {} | ^^^^^^^^^^^^^^^^^^^^^^^ - this expression has type `fn() -> bool` @@ -1591,29 +909,7 @@ LL | if let Range { start: F, end } = F..|| true {} found struct `std::ops::Range<_>` error[E0308]: mismatched types - --> $DIR/disallowed-positions.rs:182:41 - | -LL | if let Range { start: F, end } = F..|| true {} - | ^^^^^^^ expected `bool`, found closure - | - = note: expected type `bool` - found closure `[closure@$DIR/disallowed-positions.rs:182:41: 182:43]` -help: use parentheses to call this closure - | -LL | if let Range { start: F, end } = F..(|| true)() {} - | + +++ - -error[E0308]: mismatched types - --> $DIR/disallowed-positions.rs:182:8 - | -LL | if let Range { start: F, end } = F..|| true {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `bool`, found `Range<bool>` - | - = note: expected type `bool` - found struct `std::ops::Range<bool>` - -error[E0308]: mismatched types - --> $DIR/disallowed-positions.rs:190:12 + --> $DIR/disallowed-positions.rs:143:12 | LL | if let Range { start: true, end } = t..&&false {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^ - this expression has type `&&bool` @@ -1623,29 +919,8 @@ LL | if let Range { start: true, end } = t..&&false {} = note: expected type `bool` found struct `std::ops::Range<_>` -error[E0308]: mismatched types - --> $DIR/disallowed-positions.rs:190:44 - | -LL | if let Range { start: true, end } = t..&&false {} - | ^^^^^^^ expected `bool`, found `&&bool` - | -help: consider removing the `&&` - | -LL - if let Range { start: true, end } = t..&&false {} -LL + if let Range { start: true, end } = t..false {} - | - -error[E0308]: mismatched types - --> $DIR/disallowed-positions.rs:190:8 - | -LL | if let Range { start: true, end } = t..&&false {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `bool`, found `Range<bool>` - | - = note: expected type `bool` - found struct `std::ops::Range<bool>` - error[E0277]: the `?` operator can only be applied to values that implement `Try` - --> $DIR/disallowed-positions.rs:128:20 + --> $DIR/disallowed-positions.rs:99:20 | LL | if let 0 = 0? {} | ^^ the `?` operator cannot be applied to type `{integer}` @@ -1653,61 +928,7 @@ LL | if let 0 = 0? {} = help: the trait `Try` is not implemented for `{integer}` error[E0308]: mismatched types - --> $DIR/disallowed-positions.rs:202:11 - | -LL | while &let 0 = 0 {} - | ^^^^^^^^^^ expected `bool`, found `&bool` - | -help: consider removing the borrow - | -LL - while &let 0 = 0 {} -LL + while let 0 = 0 {} - | - -error[E0614]: type `bool` cannot be dereferenced - --> $DIR/disallowed-positions.rs:210:11 - | -LL | while *let 0 = 0 {} - | ^^^^^^^^^^ - -error[E0600]: cannot apply unary operator `-` to type `bool` - --> $DIR/disallowed-positions.rs:214:11 - | -LL | while -let 0 = 0 {} - | ^^^^^^^^^^ cannot apply unary operator `-` - -error[E0277]: the `?` operator can only be applied to values that implement `Try` - --> $DIR/disallowed-positions.rs:224:11 - | -LL | while (let 0 = 0)? {} - | ^^^^^^^^^^^^ the `?` operator cannot be applied to type `bool` - | - = help: the trait `Try` is not implemented for `bool` - -error[E0277]: the `?` operator can only be used in a function that returns `Result` or `Option` (or another type that implements `FromResidual`) - --> $DIR/disallowed-positions.rs:224:22 - | -LL | fn nested_within_while_expr() { - | ----------------------------- this function should return `Result` or `Option` to accept `?` -... -LL | while (let 0 = 0)? {} - | ^ cannot use the `?` operator in a function that returns `()` - | - = help: the trait `FromResidual<_>` is not implemented for `()` - -error[E0308]: mismatched types - --> $DIR/disallowed-positions.rs:244:11 - | -LL | while x = let 0 = 0 {} - | ^^^^^^^^^^^^^ expected `bool`, found `()` - | -help: you might have meant to compare for equality - | -LL | while x == let 0 = 0 {} - | + - -error[E0308]: mismatched types - --> $DIR/disallowed-positions.rs:249:11 + --> $DIR/disallowed-positions.rs:183:11 | LL | while true..(let 0 = 0) {} | ^^^^^^^^^^^^^^^^^ expected `bool`, found `Range<bool>` @@ -1716,25 +937,7 @@ LL | while true..(let 0 = 0) {} found struct `std::ops::Range<bool>` error[E0308]: mismatched types - --> $DIR/disallowed-positions.rs:253:11 - | -LL | while ..(let 0 = 0) {} - | ^^^^^^^^^^^^^ expected `bool`, found `RangeTo<bool>` - | - = note: expected type `bool` - found struct `RangeTo<bool>` - -error[E0308]: mismatched types - --> $DIR/disallowed-positions.rs:257:11 - | -LL | while (let 0 = 0).. {} - | ^^^^^^^^^^^^^ expected `bool`, found `RangeFrom<bool>` - | - = note: expected type `bool` - found struct `RangeFrom<bool>` - -error[E0308]: mismatched types - --> $DIR/disallowed-positions.rs:263:15 + --> $DIR/disallowed-positions.rs:192:15 | LL | while let Range { start: _, end: _ } = true..true && false {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^ ---- this expression has type `bool` @@ -1745,16 +948,7 @@ LL | while let Range { start: _, end: _ } = true..true && false {} found struct `std::ops::Range<_>` error[E0308]: mismatched types - --> $DIR/disallowed-positions.rs:263:11 - | -LL | while let Range { start: _, end: _ } = true..true && false {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `bool`, found `Range<bool>` - | - = note: expected type `bool` - found struct `std::ops::Range<bool>` - -error[E0308]: mismatched types - --> $DIR/disallowed-positions.rs:267:15 + --> $DIR/disallowed-positions.rs:195:15 | LL | while let Range { start: _, end: _ } = true..true || false {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^ ---- this expression has type `bool` @@ -1765,16 +959,7 @@ LL | while let Range { start: _, end: _ } = true..true || false {} found struct `std::ops::Range<_>` error[E0308]: mismatched types - --> $DIR/disallowed-positions.rs:267:11 - | -LL | while let Range { start: _, end: _ } = true..true || false {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `bool`, found `Range<bool>` - | - = note: expected type `bool` - found struct `std::ops::Range<bool>` - -error[E0308]: mismatched types - --> $DIR/disallowed-positions.rs:274:15 + --> $DIR/disallowed-positions.rs:201:15 | LL | while let Range { start: F, end } = F..|| true {} | ^^^^^^^^^^^^^^^^^^^^^^^ - this expression has type `fn() -> bool` @@ -1785,29 +970,7 @@ LL | while let Range { start: F, end } = F..|| true {} found struct `std::ops::Range<_>` error[E0308]: mismatched types - --> $DIR/disallowed-positions.rs:274:44 - | -LL | while let Range { start: F, end } = F..|| true {} - | ^^^^^^^ expected `bool`, found closure - | - = note: expected type `bool` - found closure `[closure@$DIR/disallowed-positions.rs:274:44: 274:46]` -help: use parentheses to call this closure - | -LL | while let Range { start: F, end } = F..(|| true)() {} - | + +++ - -error[E0308]: mismatched types - --> $DIR/disallowed-positions.rs:274:11 - | -LL | while let Range { start: F, end } = F..|| true {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `bool`, found `Range<bool>` - | - = note: expected type `bool` - found struct `std::ops::Range<bool>` - -error[E0308]: mismatched types - --> $DIR/disallowed-positions.rs:282:15 + --> $DIR/disallowed-positions.rs:207:15 | LL | while let Range { start: true, end } = t..&&false {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^ - this expression has type `&&bool` @@ -1817,68 +980,16 @@ LL | while let Range { start: true, end } = t..&&false {} = note: expected type `bool` found struct `std::ops::Range<_>` -error[E0308]: mismatched types - --> $DIR/disallowed-positions.rs:282:47 - | -LL | while let Range { start: true, end } = t..&&false {} - | ^^^^^^^ expected `bool`, found `&&bool` - | -help: consider removing the `&&` - | -LL - while let Range { start: true, end } = t..&&false {} -LL + while let Range { start: true, end } = t..false {} - | - -error[E0308]: mismatched types - --> $DIR/disallowed-positions.rs:282:11 - | -LL | while let Range { start: true, end } = t..&&false {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `bool`, found `Range<bool>` - | - = note: expected type `bool` - found struct `std::ops::Range<bool>` - error[E0277]: the `?` operator can only be applied to values that implement `Try` - --> $DIR/disallowed-positions.rs:220:23 + --> $DIR/disallowed-positions.rs:163:23 | LL | while let 0 = 0? {} | ^^ the `?` operator cannot be applied to type `{integer}` | = help: the trait `Try` is not implemented for `{integer}` -error[E0614]: type `bool` cannot be dereferenced - --> $DIR/disallowed-positions.rs:311:5 - | -LL | *let 0 = 0; - | ^^^^^^^^^^ - -error[E0600]: cannot apply unary operator `-` to type `bool` - --> $DIR/disallowed-positions.rs:315:5 - | -LL | -let 0 = 0; - | ^^^^^^^^^^ cannot apply unary operator `-` - -error[E0277]: the `?` operator can only be applied to values that implement `Try` - --> $DIR/disallowed-positions.rs:325:5 - | -LL | (let 0 = 0)?; - | ^^^^^^^^^^^^ the `?` operator cannot be applied to type `bool` - | - = help: the trait `Try` is not implemented for `bool` - -error[E0277]: the `?` operator can only be used in a function that returns `Result` or `Option` (or another type that implements `FromResidual`) - --> $DIR/disallowed-positions.rs:325:16 - | -LL | fn outside_if_and_while_expr() { - | ------------------------------ this function should return `Result` or `Option` to accept `?` -... -LL | (let 0 = 0)?; - | ^ cannot use the `?` operator in a function that returns `()` - | - = help: the trait `FromResidual<_>` is not implemented for `()` - error[E0308]: mismatched types - --> $DIR/disallowed-positions.rs:356:10 + --> $DIR/disallowed-positions.rs:262:10 | LL | (let Range { start: _, end: _ } = true..true || false); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ ---- this expression has type `bool` @@ -1888,24 +999,15 @@ LL | (let Range { start: _, end: _ } = true..true || false); = note: expected type `bool` found struct `std::ops::Range<_>` -error[E0308]: mismatched types - --> $DIR/disallowed-positions.rs:379:5 - | -LL | fn outside_if_and_while_expr() { - | - help: try adding a return type: `-> &bool` -... -LL | &let 0 = 0 - | ^^^^^^^^^^ expected `()`, found `&bool` - error[E0277]: the `?` operator can only be applied to values that implement `Try` - --> $DIR/disallowed-positions.rs:321:17 + --> $DIR/disallowed-positions.rs:237:17 | LL | let 0 = 0?; | ^^ the `?` operator cannot be applied to type `{integer}` | = help: the trait `Try` is not implemented for `{integer}` -error: aborting due to 215 previous errors +error: aborting due to 104 previous errors -Some errors have detailed explanations: E0277, E0308, E0600, E0614. +Some errors have detailed explanations: E0277, E0308. For more information about an error, try `rustc --explain E0277`. diff --git a/tests/ui/rfcs/rfc-2497-if-let-chains/ensure-that-let-else-does-not-interact-with-let-chains.rs b/tests/ui/rfcs/rfc-2497-if-let-chains/ensure-that-let-else-does-not-interact-with-let-chains.rs index 2a6c144350a..3c572054e3f 100644 --- a/tests/ui/rfcs/rfc-2497-if-let-chains/ensure-that-let-else-does-not-interact-with-let-chains.rs +++ b/tests/ui/rfcs/rfc-2497-if-let-chains/ensure-that-let-else-does-not-interact-with-let-chains.rs @@ -14,7 +14,6 @@ fn main() { }; let Some(n) = opt && let another = n else { //~^ ERROR a `&&` expression cannot be directly assigned in `let...else` - //~| ERROR `let` expressions are not supported here //~| ERROR mismatched types //~| ERROR mismatched types //~| ERROR expected expression, found `let` statement diff --git a/tests/ui/rfcs/rfc-2497-if-let-chains/ensure-that-let-else-does-not-interact-with-let-chains.stderr b/tests/ui/rfcs/rfc-2497-if-let-chains/ensure-that-let-else-does-not-interact-with-let-chains.stderr index 9bc3e754126..0442f1218b1 100644 --- a/tests/ui/rfcs/rfc-2497-if-let-chains/ensure-that-let-else-does-not-interact-with-let-chains.stderr +++ b/tests/ui/rfcs/rfc-2497-if-let-chains/ensure-that-let-else-does-not-interact-with-let-chains.stderr @@ -14,6 +14,8 @@ error: expected expression, found `let` statement | LL | let Some(n) = opt && let another = n else { | ^^^ + | + = note: only supported directly in conditions of `if` and `while` expressions error: a `&&` expression cannot be directly assigned in `let...else` --> $DIR/ensure-that-let-else-does-not-interact-with-let-chains.rs:15:19 @@ -27,13 +29,13 @@ LL | let Some(n) = (opt && let another = n) else { | + + error: this `if` expression is missing a block after the condition - --> $DIR/ensure-that-let-else-does-not-interact-with-let-chains.rs:24:5 + --> $DIR/ensure-that-let-else-does-not-interact-with-let-chains.rs:23:5 | LL | if let Some(n) = opt else { | ^^ | help: add a block here - --> $DIR/ensure-that-let-else-does-not-interact-with-let-chains.rs:24:25 + --> $DIR/ensure-that-let-else-does-not-interact-with-let-chains.rs:23:25 | LL | if let Some(n) = opt else { | ^ @@ -44,31 +46,31 @@ LL + let Some(n) = opt else { | error: this `if` expression is missing a block after the condition - --> $DIR/ensure-that-let-else-does-not-interact-with-let-chains.rs:28:5 + --> $DIR/ensure-that-let-else-does-not-interact-with-let-chains.rs:27:5 | LL | if let Some(n) = opt && n == 1 else { | ^^ | help: add a block here - --> $DIR/ensure-that-let-else-does-not-interact-with-let-chains.rs:28:35 + --> $DIR/ensure-that-let-else-does-not-interact-with-let-chains.rs:27:35 | LL | if let Some(n) = opt && n == 1 else { | ^ error: this `if` expression is missing a block after the condition - --> $DIR/ensure-that-let-else-does-not-interact-with-let-chains.rs:32:5 + --> $DIR/ensure-that-let-else-does-not-interact-with-let-chains.rs:31:5 | LL | if let Some(n) = opt && let another = n else { | ^^ | help: add a block here - --> $DIR/ensure-that-let-else-does-not-interact-with-let-chains.rs:32:44 + --> $DIR/ensure-that-let-else-does-not-interact-with-let-chains.rs:31:44 | LL | if let Some(n) = opt && let another = n else { | ^ error: expected `{`, found keyword `else` - --> $DIR/ensure-that-let-else-does-not-interact-with-let-chains.rs:38:33 + --> $DIR/ensure-that-let-else-does-not-interact-with-let-chains.rs:37:33 | LL | while let Some(n) = opt else { | ----- ----------------- ^^^^ expected `{` @@ -77,7 +79,7 @@ LL | while let Some(n) = opt else { | while parsing the body of this `while` expression error: expected `{`, found keyword `else` - --> $DIR/ensure-that-let-else-does-not-interact-with-let-chains.rs:44:43 + --> $DIR/ensure-that-let-else-does-not-interact-with-let-chains.rs:43:43 | LL | while let Some(n) = opt && n == 1 else { | ----- --------------------------- ^^^^ expected `{` @@ -86,7 +88,7 @@ LL | while let Some(n) = opt && n == 1 else { | while parsing the body of this `while` expression error: expected `{`, found keyword `else` - --> $DIR/ensure-that-let-else-does-not-interact-with-let-chains.rs:50:52 + --> $DIR/ensure-that-let-else-does-not-interact-with-let-chains.rs:49:52 | LL | while let Some(n) = opt && let another = n else { | ----- ------------------------------------ ^^^^ expected `{` @@ -94,14 +96,6 @@ LL | while let Some(n) = opt && let another = n else { | | this `while` condition successfully parsed | while parsing the body of this `while` expression -error: `let` expressions are not supported here - --> $DIR/ensure-that-let-else-does-not-interact-with-let-chains.rs:15:26 - | -LL | let Some(n) = opt && let another = n else { - | ^^^^^^^^^^^^^^^ - | - = note: only supported directly in conditions of `if` and `while` expressions - error[E0308]: mismatched types --> $DIR/ensure-that-let-else-does-not-interact-with-let-chains.rs:9:19 | @@ -142,6 +136,6 @@ LL | let Some(n) = opt && let another = n else { = note: expected type `bool` found enum `Option<_>` -error: aborting due to 14 previous errors +error: aborting due to 13 previous errors For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/rfcs/rfc-2497-if-let-chains/feature-gate.rs b/tests/ui/rfcs/rfc-2497-if-let-chains/feature-gate.rs index 2b407ef510c..bca7564efd8 100644 --- a/tests/ui/rfcs/rfc-2497-if-let-chains/feature-gate.rs +++ b/tests/ui/rfcs/rfc-2497-if-let-chains/feature-gate.rs @@ -43,8 +43,7 @@ fn _macros() { macro_rules! noop_expr { ($e:expr) => {}; } noop_expr!((let 0 = 1)); - //~^ ERROR `let` expressions in this position are unstable [E0658] - //~| ERROR expected expression, found `let` statement + //~^ ERROR expected expression, found `let` statement macro_rules! use_expr { ($e:expr) => { @@ -53,8 +52,7 @@ fn _macros() { } } #[cfg(FALSE)] (let 0 = 1); - //~^ ERROR `let` expressions in this position are unstable [E0658] - //~| ERROR expected expression, found `let` statement + //~^ ERROR expected expression, found `let` statement use_expr!(let 0 = 1); //~^ ERROR no rules expected the token `let` } diff --git a/tests/ui/rfcs/rfc-2497-if-let-chains/feature-gate.stderr b/tests/ui/rfcs/rfc-2497-if-let-chains/feature-gate.stderr index 7a43b71fc8b..6f74736755e 100644 --- a/tests/ui/rfcs/rfc-2497-if-let-chains/feature-gate.stderr +++ b/tests/ui/rfcs/rfc-2497-if-let-chains/feature-gate.stderr @@ -1,17 +1,21 @@ error: expected expression, found `let` statement - --> $DIR/feature-gate.rs:55:20 + --> $DIR/feature-gate.rs:54:20 | LL | #[cfg(FALSE)] (let 0 = 1); | ^^^ + | + = note: only supported directly in conditions of `if` and `while` expressions error: expected expression, found `let` statement --> $DIR/feature-gate.rs:45:17 | LL | noop_expr!((let 0 = 1)); | ^^^ + | + = note: only supported directly in conditions of `if` and `while` expressions error: no rules expected the token `let` - --> $DIR/feature-gate.rs:58:15 + --> $DIR/feature-gate.rs:56:15 | LL | macro_rules! use_expr { | --------------------- when calling this macro @@ -20,7 +24,7 @@ LL | use_expr!(let 0 = 1); | ^^^ no rules expected this token in macro call | note: while trying to match meta-variable `$e:expr` - --> $DIR/feature-gate.rs:50:10 + --> $DIR/feature-gate.rs:49:10 | LL | ($e:expr) => { | ^^^^^^^ @@ -97,24 +101,6 @@ LL | while let Range { start: _, end: _ } = (true..true) && false {} = note: see issue #53667 <https://github.com/rust-lang/rust/issues/53667> for more information = help: add `#![feature(let_chains)]` to the crate attributes to enable -error[E0658]: `let` expressions in this position are unstable - --> $DIR/feature-gate.rs:55:20 - | -LL | #[cfg(FALSE)] (let 0 = 1); - | ^^^^^^^^^ - | - = note: see issue #53667 <https://github.com/rust-lang/rust/issues/53667> for more information - = help: add `#![feature(let_chains)]` to the crate attributes to enable - -error[E0658]: `let` expressions in this position are unstable - --> $DIR/feature-gate.rs:45:17 - | -LL | noop_expr!((let 0 = 1)); - | ^^^^^^^^^ - | - = note: see issue #53667 <https://github.com/rust-lang/rust/issues/53667> for more information - = help: add `#![feature(let_chains)]` to the crate attributes to enable - -error: aborting due to 13 previous errors +error: aborting due to 11 previous errors For more information about this error, try `rustc --explain E0658`. diff --git a/tests/ui/rfcs/rfc-2497-if-let-chains/invalid-let-in-a-valid-let-context.rs b/tests/ui/rfcs/rfc-2497-if-let-chains/invalid-let-in-a-valid-let-context.rs index a942d1f4caf..dce1c19ff33 100644 --- a/tests/ui/rfcs/rfc-2497-if-let-chains/invalid-let-in-a-valid-let-context.rs +++ b/tests/ui/rfcs/rfc-2497-if-let-chains/invalid-let-in-a-valid-let-context.rs @@ -13,6 +13,7 @@ fn main() { if let Some(elem) = _opt && [1, 2, 3][let _ = &&let Some(x) = Some(42)] = 1 { //~^ ERROR expected expression, found `let` statement //~| ERROR expected expression, found `let` statement + //~| ERROR expected expression, found `let` statement true } } @@ -31,6 +32,7 @@ fn main() { { if let Some(elem) = _opt && [1, 2, 3][let _ = ()] = 1 { //~^ ERROR expected expression, found `let` statement + //~| ERROR expected expression, found `let` statement true } } diff --git a/tests/ui/rfcs/rfc-2497-if-let-chains/invalid-let-in-a-valid-let-context.stderr b/tests/ui/rfcs/rfc-2497-if-let-chains/invalid-let-in-a-valid-let-context.stderr index d1ce83c7233..247fad2e992 100644 --- a/tests/ui/rfcs/rfc-2497-if-let-chains/invalid-let-in-a-valid-let-context.stderr +++ b/tests/ui/rfcs/rfc-2497-if-let-chains/invalid-let-in-a-valid-let-context.stderr @@ -3,36 +3,64 @@ error: expected expression, found `let` statement | LL | let _ = &&let Some(x) = Some(42); | ^^^ + | + = note: only supported directly in conditions of `if` and `while` expressions error: expected expression, found `let` statement --> $DIR/invalid-let-in-a-valid-let-context.rs:13:47 | LL | if let Some(elem) = _opt && [1, 2, 3][let _ = &&let Some(x) = Some(42)] = 1 { | ^^^ + | + = note: only supported directly in conditions of `if` and `while` expressions error: expected expression, found `let` statement --> $DIR/invalid-let-in-a-valid-let-context.rs:13:57 | LL | if let Some(elem) = _opt && [1, 2, 3][let _ = &&let Some(x) = Some(42)] = 1 { | ^^^ + | + = note: only supported directly in conditions of `if` and `while` expressions + +error: expected expression, found `let` statement + --> $DIR/invalid-let-in-a-valid-let-context.rs:13:12 + | +LL | if let Some(elem) = _opt && [1, 2, 3][let _ = &&let Some(x) = Some(42)] = 1 { + | ^^^^^^^^^^^^^^^^^^^^^ + | + = note: only supported directly in conditions of `if` and `while` expressions error: expected expression, found `let` statement - --> $DIR/invalid-let-in-a-valid-let-context.rs:23:23 + --> $DIR/invalid-let-in-a-valid-let-context.rs:24:23 | LL | [1, 2, 3][let _ = ()]; | ^^^ + | + = note: only supported directly in conditions of `if` and `while` expressions error: expected expression, found `let` statement - --> $DIR/invalid-let-in-a-valid-let-context.rs:32:47 + --> $DIR/invalid-let-in-a-valid-let-context.rs:33:47 | LL | if let Some(elem) = _opt && [1, 2, 3][let _ = ()] = 1 { | ^^^ + | + = note: only supported directly in conditions of `if` and `while` expressions + +error: expected expression, found `let` statement + --> $DIR/invalid-let-in-a-valid-let-context.rs:33:12 + | +LL | if let Some(elem) = _opt && [1, 2, 3][let _ = ()] = 1 { + | ^^^^^^^^^^^^^^^^^^^^^ + | + = note: only supported directly in conditions of `if` and `while` expressions error: expected expression, found `let` statement - --> $DIR/invalid-let-in-a-valid-let-context.rs:40:21 + --> $DIR/invalid-let-in-a-valid-let-context.rs:42:21 | LL | let x = let y = 1; | ^^^ + | + = note: only supported directly in conditions of `if` and `while` expressions -error: aborting due to 6 previous errors +error: aborting due to 8 previous errors diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/fallback.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/fallback.rs new file mode 100644 index 00000000000..da2778f6101 --- /dev/null +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/fallback.rs @@ -0,0 +1,16 @@ +// check-pass + +#![feature(effects)] + +pub const fn owo() {} + +fn main() { + // make sure falling back ty/int vars doesn't cause const fallback to be skipped... + // See issue: 115791. + let _ = 1; + if false { + let x = panic!(); + } + + let _ = owo; +} diff --git a/tests/ui/sanitize/cfg.rs b/tests/ui/sanitize/cfg.rs index 523de1ceaee..f8ccf3b042d 100644 --- a/tests/ui/sanitize/cfg.rs +++ b/tests/ui/sanitize/cfg.rs @@ -1,15 +1,15 @@ // Verifies that when compiling with -Zsanitizer=option, // the `#[cfg(sanitize = "option")]` attribute is configured. -// needs-sanitizer-support // check-pass // revisions: address cfi kcfi leak memory thread //[address]needs-sanitizer-address //[address]compile-flags: -Zsanitizer=address --cfg address //[cfi]needs-sanitizer-cfi -//[cfi]compile-flags: -Zsanitizer=cfi --cfg cfi -Clto -//[kcfi]needs-sanitizer-kcfi -//[kcfi]compile-flags: -Zsanitizer=kcfi --cfg kcfi +//[cfi]compile-flags: -Zsanitizer=cfi --cfg cfi +//[cfi]compile-flags: -Clto -Ccodegen-units=1 -Ctarget-feature=-crt-static +//[kcfi]needs-llvm-components: x86 +//[kcfi]compile-flags: -Zsanitizer=kcfi --cfg kcfi --target x86_64-unknown-none //[leak]needs-sanitizer-leak //[leak]compile-flags: -Zsanitizer=leak --cfg leak //[memory]needs-sanitizer-memory @@ -17,7 +17,14 @@ //[thread]needs-sanitizer-thread //[thread]compile-flags: -Zsanitizer=thread --cfg thread -#![feature(cfg_sanitize)] +#![feature(cfg_sanitize, no_core, lang_items)] +#![crate_type="lib"] +#![no_core] + +#[lang="sized"] +trait Sized { } +#[lang="copy"] +trait Copy { } #[cfg(all(sanitize = "address", address))] fn main() {} @@ -36,3 +43,7 @@ fn main() {} #[cfg(all(sanitize = "thread", thread))] fn main() {} + +pub fn check() { + main(); +} diff --git a/tests/ui/span/issue-29595.stderr b/tests/ui/span/issue-29595.stderr index 92445e40731..7d603cdbfe5 100644 --- a/tests/ui/span/issue-29595.stderr +++ b/tests/ui/span/issue-29595.stderr @@ -3,6 +3,12 @@ error[E0277]: the trait bound `u8: Tr` is not satisfied | LL | let a: u8 = Tr::C; | ^^^^^ the trait `Tr` is not implemented for `u8` + | +help: this trait has no implementations, consider adding one + --> $DIR/issue-29595.rs:1:1 + | +LL | trait Tr { + | ^^^^^^^^ error: aborting due to previous error diff --git a/tests/ui/span/send-is-not-static-std-sync.rs b/tests/ui/span/send-is-not-static-std-sync.rs index f8ab5243c22..9c1ee287154 100644 --- a/tests/ui/span/send-is-not-static-std-sync.rs +++ b/tests/ui/span/send-is-not-static-std-sync.rs @@ -46,7 +46,7 @@ fn channel() { tx.send(&z).unwrap(); } //~^^ ERROR `z` does not live long enough - // (channels lack #[may_dangle], thus their dtors are implicit uses of `z`) + tx.use_ref(); // (channel drop glue does not use `z` => needs explicit use) } fn main() {} diff --git a/tests/ui/span/send-is-not-static-std-sync.stderr b/tests/ui/span/send-is-not-static-std-sync.stderr index eaba415adaa..46534b39168 100644 --- a/tests/ui/span/send-is-not-static-std-sync.stderr +++ b/tests/ui/span/send-is-not-static-std-sync.stderr @@ -75,11 +75,9 @@ LL | tx.send(&z).unwrap(); | ^^ borrowed value does not live long enough LL | } | - `z` dropped here while still borrowed -... -LL | } - | - borrow might be used here, when `tx` is dropped and runs the `Drop` code for type `Sender` - | - = note: values in a scope are dropped in the opposite order they are defined +LL | +LL | tx.use_ref(); // (channel drop glue does not use `z` => needs explicit use) + | -- borrow later used here error: aborting due to 6 previous errors diff --git a/tests/ui/specialization/issue-38091.stderr b/tests/ui/specialization/issue-38091.stderr index f2210a40719..4d840482b46 100644 --- a/tests/ui/specialization/issue-38091.stderr +++ b/tests/ui/specialization/issue-38091.stderr @@ -14,6 +14,11 @@ error[E0277]: the trait bound `(): Valid` is not satisfied LL | default type Ty = (); | ^^ the trait `Valid` is not implemented for `()` | +help: this trait has no implementations, consider adding one + --> $DIR/issue-38091.rs:20:1 + | +LL | trait Valid {} + | ^^^^^^^^^^^ note: required by a bound in `Iterate::Ty` --> $DIR/issue-38091.rs:5:14 | diff --git a/tests/ui/suggestions/issue-89333.stderr b/tests/ui/suggestions/issue-89333.stderr index f73f1147d5d..4739f11ddad 100644 --- a/tests/ui/suggestions/issue-89333.stderr +++ b/tests/ui/suggestions/issue-89333.stderr @@ -4,6 +4,11 @@ error[E0277]: the trait bound `for<'a> &'a _: Trait` is not satisfied LL | test(&|| 0); | ^^^^ the trait `for<'a> Trait` is not implemented for `&'a _` | +help: this trait has no implementations, consider adding one + --> $DIR/issue-89333.rs:9:1 + | +LL | trait Trait {} + | ^^^^^^^^^^^ note: required by a bound in `test` --> $DIR/issue-89333.rs:11:55 | diff --git a/tests/ui/thir-print/thir-flat-const-variant.stdout b/tests/ui/thir-print/thir-flat-const-variant.stdout index af7f2b67152..7bddc925996 100644 --- a/tests/ui/thir-print/thir-flat-const-variant.stdout +++ b/tests/ui/thir-print/thir-flat-const-variant.stdout @@ -1,11 +1,7 @@ DefId(0:8 ~ thir_flat_const_variant[1f54]::{impl#0}::BAR1): Thir { body_type: Const( - Adt( - Foo, - [ - ], - ), + Foo, ), arms: [], blocks: [], @@ -50,11 +46,7 @@ Thir { base: None, }, ), - ty: Adt( - Foo, - [ - ], - ), + ty: Foo, temp_lifetime: Some( Node(3), ), @@ -68,11 +60,7 @@ Thir { ), value: e2, }, - ty: Adt( - Foo, - [ - ], - ), + ty: Foo, temp_lifetime: Some( Node(3), ), @@ -84,11 +72,7 @@ Thir { lint_level: Inherited, value: e3, }, - ty: Adt( - Foo, - [ - ], - ), + ty: Foo, temp_lifetime: Some( Node(3), ), @@ -102,11 +86,7 @@ Thir { DefId(0:9 ~ thir_flat_const_variant[1f54]::{impl#0}::BAR2): Thir { body_type: Const( - Adt( - Foo, - [ - ], - ), + Foo, ), arms: [], blocks: [], @@ -151,11 +131,7 @@ Thir { base: None, }, ), - ty: Adt( - Foo, - [ - ], - ), + ty: Foo, temp_lifetime: Some( Node(3), ), @@ -169,11 +145,7 @@ Thir { ), value: e2, }, - ty: Adt( - Foo, - [ - ], - ), + ty: Foo, temp_lifetime: Some( Node(3), ), @@ -185,11 +157,7 @@ Thir { lint_level: Inherited, value: e3, }, - ty: Adt( - Foo, - [ - ], - ), + ty: Foo, temp_lifetime: Some( Node(3), ), @@ -203,11 +171,7 @@ Thir { DefId(0:10 ~ thir_flat_const_variant[1f54]::{impl#0}::BAR3): Thir { body_type: Const( - Adt( - Foo, - [ - ], - ), + Foo, ), arms: [], blocks: [], @@ -252,11 +216,7 @@ Thir { base: None, }, ), - ty: Adt( - Foo, - [ - ], - ), + ty: Foo, temp_lifetime: Some( Node(3), ), @@ -270,11 +230,7 @@ Thir { ), value: e2, }, - ty: Adt( - Foo, - [ - ], - ), + ty: Foo, temp_lifetime: Some( Node(3), ), @@ -286,11 +242,7 @@ Thir { lint_level: Inherited, value: e3, }, - ty: Adt( - Foo, - [ - ], - ), + ty: Foo, temp_lifetime: Some( Node(3), ), @@ -304,11 +256,7 @@ Thir { DefId(0:11 ~ thir_flat_const_variant[1f54]::{impl#0}::BAR4): Thir { body_type: Const( - Adt( - Foo, - [ - ], - ), + Foo, ), arms: [], blocks: [], @@ -353,11 +301,7 @@ Thir { base: None, }, ), - ty: Adt( - Foo, - [ - ], - ), + ty: Foo, temp_lifetime: Some( Node(3), ), @@ -371,11 +315,7 @@ Thir { ), value: e2, }, - ty: Adt( - Foo, - [ - ], - ), + ty: Foo, temp_lifetime: Some( Node(3), ), @@ -387,11 +327,7 @@ Thir { lint_level: Inherited, value: e3, }, - ty: Adt( - Foo, - [ - ], - ), + ty: Foo, temp_lifetime: Some( Node(3), ), diff --git a/tests/ui/thir-print/thir-tree-match.stdout b/tests/ui/thir-print/thir-tree-match.stdout index 0e21b98307b..3fc130f0176 100644 --- a/tests/ui/thir-print/thir-tree-match.stdout +++ b/tests/ui/thir-print/thir-tree-match.stdout @@ -1,13 +1,13 @@ DefId(0:16 ~ thir_tree_match[fcf8]::has_match): params: [ Param { - ty: Adt(Foo, []) + ty: Foo ty_span: Some($DIR/thir-tree-match.rs:15:19: 15:22 (#0)) self_kind: None hir_id: Some(HirId(DefId(0:16 ~ thir_tree_match[fcf8]::has_match).1)) param: Some( Pat: { - ty: Adt(Foo, []) + ty: Foo span: $DIR/thir-tree-match.rs:15:14: 15:17 (#0) kind: PatKind { Binding { @@ -15,7 +15,7 @@ params: [ name: "foo" mode: ByValue var: LocalVarId(HirId(DefId(0:16 ~ thir_tree_match[fcf8]::has_match).2)) - ty: Adt(Foo, []) + ty: Foo is_primary: true subpattern: None } @@ -73,7 +73,7 @@ body: Match { scrutinee: Expr { - ty: Adt(Foo, []) + ty: Foo temp_lifetime: Some(Node(26)) span: $DIR/thir-tree-match.rs:16:11: 16:14 (#0) kind: @@ -82,7 +82,7 @@ body: lint_level: Explicit(HirId(DefId(0:16 ~ thir_tree_match[fcf8]::has_match).4)) value: Expr { - ty: Adt(Foo, []) + ty: Foo temp_lifetime: Some(Node(26)) span: $DIR/thir-tree-match.rs:16:11: 16:14 (#0) kind: @@ -96,7 +96,7 @@ body: Arm { pattern: Pat: { - ty: Adt(Foo, []) + ty: Foo span: $DIR/thir-tree-match.rs:17:9: 17:32 (#0) kind: PatKind { Variant { @@ -110,7 +110,7 @@ body: variant_index: 0 subpatterns: [ Pat: { - ty: Adt(Bar, []) + ty: Bar span: $DIR/thir-tree-match.rs:17:21: 17:31 (#0) kind: PatKind { Variant { @@ -169,7 +169,7 @@ body: Arm { pattern: Pat: { - ty: Adt(Foo, []) + ty: Foo span: $DIR/thir-tree-match.rs:18:9: 18:23 (#0) kind: PatKind { Variant { @@ -183,7 +183,7 @@ body: variant_index: 0 subpatterns: [ Pat: { - ty: Adt(Bar, []) + ty: Bar span: $DIR/thir-tree-match.rs:18:21: 18:22 (#0) kind: PatKind { Wild @@ -232,7 +232,7 @@ body: Arm { pattern: Pat: { - ty: Adt(Foo, []) + ty: Foo span: $DIR/thir-tree-match.rs:19:9: 19:20 (#0) kind: PatKind { Variant { diff --git a/tests/ui/trait-bounds/issue-82038.stderr b/tests/ui/trait-bounds/issue-82038.stderr index f37e3286f4b..30bb4a0a850 100644 --- a/tests/ui/trait-bounds/issue-82038.stderr +++ b/tests/ui/trait-bounds/issue-82038.stderr @@ -3,6 +3,12 @@ error[E0277]: the trait bound `bool: Foo` is not satisfied | LL | <bool as Foo>::my_method(); | ^^^^ the trait `Foo` is not implemented for `bool` + | +help: this trait has no implementations, consider adding one + --> $DIR/issue-82038.rs:3:1 + | +LL | trait Foo { + | ^^^^^^^^^ error: aborting due to previous error diff --git a/tests/ui/traits/bound/on-structs-and-enums-in-fns.stderr b/tests/ui/traits/bound/on-structs-and-enums-in-fns.stderr index 61237a63e32..530264b344a 100644 --- a/tests/ui/traits/bound/on-structs-and-enums-in-fns.stderr +++ b/tests/ui/traits/bound/on-structs-and-enums-in-fns.stderr @@ -4,6 +4,11 @@ error[E0277]: the trait bound `u32: Trait` is not satisfied LL | fn explode(x: Foo<u32>) {} | ^^^^^^^^ the trait `Trait` is not implemented for `u32` | +help: this trait has no implementations, consider adding one + --> $DIR/on-structs-and-enums-in-fns.rs:1:1 + | +LL | trait Trait {} + | ^^^^^^^^^^^ note: required by a bound in `Foo` --> $DIR/on-structs-and-enums-in-fns.rs:3:14 | @@ -16,6 +21,11 @@ error[E0277]: the trait bound `f32: Trait` is not satisfied LL | fn kaboom(y: Bar<f32>) {} | ^^^^^^^^ the trait `Trait` is not implemented for `f32` | +help: this trait has no implementations, consider adding one + --> $DIR/on-structs-and-enums-in-fns.rs:1:1 + | +LL | trait Trait {} + | ^^^^^^^^^^^ note: required by a bound in `Bar` --> $DIR/on-structs-and-enums-in-fns.rs:7:12 | diff --git a/tests/ui/traits/bound/on-structs-and-enums-in-impls.stderr b/tests/ui/traits/bound/on-structs-and-enums-in-impls.stderr index 8a43742260b..372bbabbd86 100644 --- a/tests/ui/traits/bound/on-structs-and-enums-in-impls.stderr +++ b/tests/ui/traits/bound/on-structs-and-enums-in-impls.stderr @@ -4,6 +4,11 @@ error[E0277]: the trait bound `u16: Trait` is not satisfied LL | impl PolyTrait<Foo<u16>> for Struct { | ^^^^^^^^^^^^^^^^^^^ the trait `Trait` is not implemented for `u16` | +help: this trait has no implementations, consider adding one + --> $DIR/on-structs-and-enums-in-impls.rs:1:1 + | +LL | trait Trait {} + | ^^^^^^^^^^^ note: required by a bound in `Foo` --> $DIR/on-structs-and-enums-in-impls.rs:3:14 | diff --git a/tests/ui/traits/bound/on-structs-and-enums-locals.stderr b/tests/ui/traits/bound/on-structs-and-enums-locals.stderr index 20bbe69c059..01cf76c62d5 100644 --- a/tests/ui/traits/bound/on-structs-and-enums-locals.stderr +++ b/tests/ui/traits/bound/on-structs-and-enums-locals.stderr @@ -4,6 +4,11 @@ error[E0277]: the trait bound `usize: Trait` is not satisfied LL | let baz: Foo<usize> = loop { }; | ^^^^^^^^^^ the trait `Trait` is not implemented for `usize` | +help: this trait has no implementations, consider adding one + --> $DIR/on-structs-and-enums-locals.rs:1:1 + | +LL | trait Trait { + | ^^^^^^^^^^^ note: required by a bound in `Foo` --> $DIR/on-structs-and-enums-locals.rs:5:14 | @@ -16,6 +21,11 @@ error[E0277]: the trait bound `{integer}: Trait` is not satisfied LL | x: 3 | ^ the trait `Trait` is not implemented for `{integer}` | +help: this trait has no implementations, consider adding one + --> $DIR/on-structs-and-enums-locals.rs:1:1 + | +LL | trait Trait { + | ^^^^^^^^^^^ note: required by a bound in `Foo` --> $DIR/on-structs-and-enums-locals.rs:5:14 | diff --git a/tests/ui/traits/bound/on-structs-and-enums-static.stderr b/tests/ui/traits/bound/on-structs-and-enums-static.stderr index fda734e8571..fa14aff684d 100644 --- a/tests/ui/traits/bound/on-structs-and-enums-static.stderr +++ b/tests/ui/traits/bound/on-structs-and-enums-static.stderr @@ -4,6 +4,11 @@ error[E0277]: the trait bound `usize: Trait` is not satisfied LL | static X: Foo<usize> = Foo { | ^^^^^^^^^^ the trait `Trait` is not implemented for `usize` | +help: this trait has no implementations, consider adding one + --> $DIR/on-structs-and-enums-static.rs:1:1 + | +LL | trait Trait { + | ^^^^^^^^^^^ note: required by a bound in `Foo` --> $DIR/on-structs-and-enums-static.rs:5:14 | diff --git a/tests/ui/traits/bound/on-structs-and-enums.stderr b/tests/ui/traits/bound/on-structs-and-enums.stderr index fe05b86344b..606f764852f 100644 --- a/tests/ui/traits/bound/on-structs-and-enums.stderr +++ b/tests/ui/traits/bound/on-structs-and-enums.stderr @@ -20,6 +20,11 @@ error[E0277]: the trait bound `isize: Trait` is not satisfied LL | a: Foo<isize>, | ^^^^^^^^^^ the trait `Trait` is not implemented for `isize` | +help: this trait has no implementations, consider adding one + --> $DIR/on-structs-and-enums.rs:1:1 + | +LL | trait Trait {} + | ^^^^^^^^^^^ note: required by a bound in `Foo` --> $DIR/on-structs-and-enums.rs:3:14 | @@ -32,6 +37,11 @@ error[E0277]: the trait bound `usize: Trait` is not satisfied LL | Quux(Bar<usize>), | ^^^^^^^^^^ the trait `Trait` is not implemented for `usize` | +help: this trait has no implementations, consider adding one + --> $DIR/on-structs-and-enums.rs:1:1 + | +LL | trait Trait {} + | ^^^^^^^^^^^ note: required by a bound in `Bar` --> $DIR/on-structs-and-enums.rs:7:12 | @@ -76,6 +86,11 @@ error[E0277]: the trait bound `i32: Trait` is not satisfied LL | Foo<i32>, | ^^^^^^^^ the trait `Trait` is not implemented for `i32` | +help: this trait has no implementations, consider adding one + --> $DIR/on-structs-and-enums.rs:1:1 + | +LL | trait Trait {} + | ^^^^^^^^^^^ note: required by a bound in `Foo` --> $DIR/on-structs-and-enums.rs:3:14 | @@ -88,6 +103,11 @@ error[E0277]: the trait bound `u8: Trait` is not satisfied LL | DictionaryLike { field: Bar<u8> }, | ^^^^^^^ the trait `Trait` is not implemented for `u8` | +help: this trait has no implementations, consider adding one + --> $DIR/on-structs-and-enums.rs:1:1 + | +LL | trait Trait {} + | ^^^^^^^^^^^ note: required by a bound in `Bar` --> $DIR/on-structs-and-enums.rs:7:12 | diff --git a/tests/ui/traits/deny-builtin-object-impl.current.stderr b/tests/ui/traits/deny-builtin-object-impl.current.stderr index 5c1987426f7..8ca3d3a057f 100644 --- a/tests/ui/traits/deny-builtin-object-impl.current.stderr +++ b/tests/ui/traits/deny-builtin-object-impl.current.stderr @@ -4,6 +4,11 @@ error[E0277]: the trait bound `dyn NotObject: NotObject` is not satisfied LL | test_not_object::<dyn NotObject>(); | ^^^^^^^^^^^^^ the trait `NotObject` is not implemented for `dyn NotObject` | +help: this trait has no implementations, consider adding one + --> $DIR/deny-builtin-object-impl.rs:10:1 + | +LL | trait NotObject {} + | ^^^^^^^^^^^^^^^ note: required by a bound in `test_not_object` --> $DIR/deny-builtin-object-impl.rs:14:23 | diff --git a/tests/ui/traits/deny-builtin-object-impl.next.stderr b/tests/ui/traits/deny-builtin-object-impl.next.stderr index 5c1987426f7..8ca3d3a057f 100644 --- a/tests/ui/traits/deny-builtin-object-impl.next.stderr +++ b/tests/ui/traits/deny-builtin-object-impl.next.stderr @@ -4,6 +4,11 @@ error[E0277]: the trait bound `dyn NotObject: NotObject` is not satisfied LL | test_not_object::<dyn NotObject>(); | ^^^^^^^^^^^^^ the trait `NotObject` is not implemented for `dyn NotObject` | +help: this trait has no implementations, consider adding one + --> $DIR/deny-builtin-object-impl.rs:10:1 + | +LL | trait NotObject {} + | ^^^^^^^^^^^^^^^ note: required by a bound in `test_not_object` --> $DIR/deny-builtin-object-impl.rs:14:23 | diff --git a/tests/ui/traits/dont-autoderef-ty-with-escaping-var.stderr b/tests/ui/traits/dont-autoderef-ty-with-escaping-var.stderr index 263c59ee327..a5d0e6ab095 100644 --- a/tests/ui/traits/dont-autoderef-ty-with-escaping-var.stderr +++ b/tests/ui/traits/dont-autoderef-ty-with-escaping-var.stderr @@ -10,6 +10,11 @@ error[E0277]: the trait bound `for<'a> &'a mut Vec<&'a u32>: Foo<'static, i32>` LL | <i32 as RefFoo<i32>>::ref_foo(unknown); | ^^^ the trait `for<'a> Foo<'static, i32>` is not implemented for `&'a mut Vec<&'a u32>` | +help: this trait has no implementations, consider adding one + --> $DIR/dont-autoderef-ty-with-escaping-var.rs:3:1 + | +LL | trait Foo<'x, T> {} + | ^^^^^^^^^^^^^^^^ note: required for `i32` to implement `RefFoo<i32>` --> $DIR/dont-autoderef-ty-with-escaping-var.rs:9:9 | diff --git a/tests/ui/traits/impl-bounds-checking.stderr b/tests/ui/traits/impl-bounds-checking.stderr index 1f969efe114..bfa8213abe7 100644 --- a/tests/ui/traits/impl-bounds-checking.stderr +++ b/tests/ui/traits/impl-bounds-checking.stderr @@ -4,6 +4,11 @@ error[E0277]: the trait bound `isize: Clone2` is not satisfied LL | impl Getter<isize> for isize { | ^^^^^ the trait `Clone2` is not implemented for `isize` | +help: this trait has no implementations, consider adding one + --> $DIR/impl-bounds-checking.rs:1:1 + | +LL | pub trait Clone2 { + | ^^^^^^^^^^^^^^^^ note: required by a bound in `Getter` --> $DIR/impl-bounds-checking.rs:6:17 | diff --git a/tests/ui/traits/new-solver/canonicalize-effect-var.rs b/tests/ui/traits/new-solver/canonicalize-effect-var.rs new file mode 100644 index 00000000000..35b69ed1a6b --- /dev/null +++ b/tests/ui/traits/new-solver/canonicalize-effect-var.rs @@ -0,0 +1,22 @@ +// compile-flags: -Ztrait-solver=next +// check-pass + +#![feature(effects)] +#![feature(const_trait_impl)] + +#[const_trait] +trait Foo { + fn foo(); +} + +trait Bar {} + +impl const Foo for i32 { + fn foo() {} +} + +impl<T> const Foo for T where T: Bar { + fn foo() {} +} + +fn main() {} diff --git a/tests/ui/traits/new-solver/projection-discr-kind.stderr b/tests/ui/traits/new-solver/projection-discr-kind.stderr index 03e28f993e2..e14953f19ff 100644 --- a/tests/ui/traits/new-solver/projection-discr-kind.stderr +++ b/tests/ui/traits/new-solver/projection-discr-kind.stderr @@ -6,6 +6,11 @@ LL | needs_bar(std::mem::discriminant(&x)); | | | required by a bound introduced by this call | +help: this trait has no implementations, consider adding one + --> $DIR/projection-discr-kind.rs:10:1 + | +LL | trait Bar {} + | ^^^^^^^^^ note: required by a bound in `needs_bar` --> $DIR/projection-discr-kind.rs:11:22 | diff --git a/tests/ui/traits/non_lifetime_binders/capture-late-ct-in-anon.rs b/tests/ui/traits/non_lifetime_binders/capture-late-ct-in-anon.rs index 91c6dfb8e0a..bbae67f0bad 100644 --- a/tests/ui/traits/non_lifetime_binders/capture-late-ct-in-anon.rs +++ b/tests/ui/traits/non_lifetime_binders/capture-late-ct-in-anon.rs @@ -4,7 +4,7 @@ fn b() where for<const C: usize> [(); C]: Copy, - //~^ ERROR cannot capture late-bound const parameter in a constant + //~^ ERROR cannot capture late-bound const parameter in constant { } diff --git a/tests/ui/traits/non_lifetime_binders/capture-late-ct-in-anon.stderr b/tests/ui/traits/non_lifetime_binders/capture-late-ct-in-anon.stderr index 69bb605bf41..d65892ec6df 100644 --- a/tests/ui/traits/non_lifetime_binders/capture-late-ct-in-anon.stderr +++ b/tests/ui/traits/non_lifetime_binders/capture-late-ct-in-anon.stderr @@ -7,7 +7,7 @@ LL | #![feature(non_lifetime_binders)] = note: see issue #108185 <https://github.com/rust-lang/rust/issues/108185> for more information = note: `#[warn(incomplete_features)]` on by default -error: cannot capture late-bound const parameter in a constant +error: cannot capture late-bound const parameter in constant --> $DIR/capture-late-ct-in-anon.rs:6:30 | LL | for<const C: usize> [(); C]: Copy, diff --git a/tests/ui/traits/non_lifetime_binders/fail.stderr b/tests/ui/traits/non_lifetime_binders/fail.stderr index 7bd02550fb3..240bcef7df5 100644 --- a/tests/ui/traits/non_lifetime_binders/fail.stderr +++ b/tests/ui/traits/non_lifetime_binders/fail.stderr @@ -13,6 +13,11 @@ error[E0277]: the trait bound `T: Trait` is not satisfied LL | fail(); | ^^^^ the trait `Trait` is not implemented for `T` | +help: this trait has no implementations, consider adding one + --> $DIR/fail.rs:6:1 + | +LL | trait Trait {} + | ^^^^^^^^^^^ note: required by a bound in `fail` --> $DIR/fail.rs:10:15 | diff --git a/tests/ui/traits/non_lifetime_binders/late-bound-in-anon-ct.rs b/tests/ui/traits/non_lifetime_binders/late-bound-in-anon-ct.rs index 3903bfe9bcf..64f09f823fc 100644 --- a/tests/ui/traits/non_lifetime_binders/late-bound-in-anon-ct.rs +++ b/tests/ui/traits/non_lifetime_binders/late-bound-in-anon-ct.rs @@ -5,7 +5,7 @@ fn foo() -> usize where for<T> [i32; { let _: T = todo!(); 0 }]:, - //~^ ERROR cannot capture late-bound type parameter in a constant + //~^ ERROR cannot capture late-bound type parameter in constant {} fn main() {} diff --git a/tests/ui/traits/non_lifetime_binders/late-bound-in-anon-ct.stderr b/tests/ui/traits/non_lifetime_binders/late-bound-in-anon-ct.stderr index fafff02dea6..dc54e1acc39 100644 --- a/tests/ui/traits/non_lifetime_binders/late-bound-in-anon-ct.stderr +++ b/tests/ui/traits/non_lifetime_binders/late-bound-in-anon-ct.stderr @@ -15,7 +15,7 @@ LL | #![feature(non_lifetime_binders, generic_const_exprs)] | = note: see issue #76560 <https://github.com/rust-lang/rust/issues/76560> for more information -error: cannot capture late-bound type parameter in a constant +error: cannot capture late-bound type parameter in constant --> $DIR/late-bound-in-anon-ct.rs:7:27 | LL | for<T> [i32; { let _: T = todo!(); 0 }]:, diff --git a/tests/ui/traits/object-does-not-impl-trait.stderr b/tests/ui/traits/object-does-not-impl-trait.stderr index f1dd508a467..81d67255a0b 100644 --- a/tests/ui/traits/object-does-not-impl-trait.stderr +++ b/tests/ui/traits/object-does-not-impl-trait.stderr @@ -6,6 +6,11 @@ LL | fn take_object(f: Box<dyn Foo>) { take_foo(f); } | | | required by a bound introduced by this call | +help: this trait has no implementations, consider adding one + --> $DIR/object-does-not-impl-trait.rs:4:1 + | +LL | trait Foo {} + | ^^^^^^^^^ note: required by a bound in `take_foo` --> $DIR/object-does-not-impl-trait.rs:5:15 | diff --git a/tests/ui/traits/vtable-res-trait-param.stderr b/tests/ui/traits/vtable-res-trait-param.stderr index 2b3e3de9b1a..4cfceefb24c 100644 --- a/tests/ui/traits/vtable-res-trait-param.stderr +++ b/tests/ui/traits/vtable-res-trait-param.stderr @@ -6,6 +6,11 @@ LL | b.gimme_an_a(y) | | | required by a bound introduced by this call | +help: this trait has no implementations, consider adding one + --> $DIR/vtable-res-trait-param.rs:1:1 + | +LL | trait TraitA { + | ^^^^^^^^^^^^ note: required by a bound in `TraitB::gimme_an_a` --> $DIR/vtable-res-trait-param.rs:6:21 | diff --git a/tests/ui/trivial-bounds/trivial-bounds-leak.stderr b/tests/ui/trivial-bounds/trivial-bounds-leak.stderr index 02c5d5d2484..be472a50769 100644 --- a/tests/ui/trivial-bounds/trivial-bounds-leak.stderr +++ b/tests/ui/trivial-bounds/trivial-bounds-leak.stderr @@ -27,6 +27,12 @@ LL | Foo::test(&4i32); | --------- ^^^^^ the trait `Foo` is not implemented for `i32` | | | required by a bound introduced by this call + | +help: this trait has no implementations, consider adding one + --> $DIR/trivial-bounds-leak.rs:4:1 + | +LL | pub trait Foo { + | ^^^^^^^^^^^^^ error[E0277]: the trait bound `i32: Foo` is not satisfied --> $DIR/trivial-bounds-leak.rs:26:22 @@ -36,6 +42,11 @@ LL | generic_function(5i32); | | | required by a bound introduced by this call | +help: this trait has no implementations, consider adding one + --> $DIR/trivial-bounds-leak.rs:4:1 + | +LL | pub trait Foo { + | ^^^^^^^^^^^^^ note: required by a bound in `generic_function` --> $DIR/trivial-bounds-leak.rs:29:24 | diff --git a/tests/ui/type-alias-impl-trait/escaping-bound-var.rs b/tests/ui/type-alias-impl-trait/escaping-bound-var.rs new file mode 100644 index 00000000000..bf27e76db2b --- /dev/null +++ b/tests/ui/type-alias-impl-trait/escaping-bound-var.rs @@ -0,0 +1,22 @@ +#![feature(type_alias_impl_trait)] + +pub trait Trait<'a> { + type Assoc; +} + +trait Test<'a> {} + +pub type Foo = impl for<'a> Trait<'a, Assoc = impl Test<'a>>; +//~^ ERROR cannot capture late-bound lifetime in type alias impl trait + +impl Trait<'_> for () { + type Assoc = (); +} + +impl Test<'_> for () {} + +fn constrain() -> Foo { + () +} + +fn main() {} diff --git a/tests/ui/type-alias-impl-trait/escaping-bound-var.stderr b/tests/ui/type-alias-impl-trait/escaping-bound-var.stderr new file mode 100644 index 00000000000..8205a60ccdd --- /dev/null +++ b/tests/ui/type-alias-impl-trait/escaping-bound-var.stderr @@ -0,0 +1,8 @@ +error: cannot capture late-bound lifetime in type alias impl trait + --> $DIR/escaping-bound-var.rs:9:57 + | +LL | pub type Foo = impl for<'a> Trait<'a, Assoc = impl Test<'a>>; + | -- lifetime defined here ^^ + +error: aborting due to previous error + diff --git a/tests/ui/type-alias-impl-trait/indirect-recursion-issue-112047.rs b/tests/ui/type-alias-impl-trait/indirect-recursion-issue-112047.rs new file mode 100644 index 00000000000..baa22e1ce18 --- /dev/null +++ b/tests/ui/type-alias-impl-trait/indirect-recursion-issue-112047.rs @@ -0,0 +1,29 @@ +// edition: 2021 +// build-fail +//~^^ ERROR overflow evaluating the requirement `<() as Recur>::Recur == _` + +#![feature(impl_trait_in_assoc_type)] + +use core::future::Future; + +trait Recur { + type Recur: Future<Output = ()>; + + fn recur(self) -> Self::Recur; +} + +async fn recur(t: impl Recur) { + t.recur().await; +} + +impl Recur for () { + type Recur = impl Future<Output = ()>; + + fn recur(self) -> Self::Recur { + async move { recur(self).await; } + } +} + +fn main() { + recur(()); +} diff --git a/tests/ui/type-alias-impl-trait/indirect-recursion-issue-112047.stderr b/tests/ui/type-alias-impl-trait/indirect-recursion-issue-112047.stderr new file mode 100644 index 00000000000..0238694c24d --- /dev/null +++ b/tests/ui/type-alias-impl-trait/indirect-recursion-issue-112047.stderr @@ -0,0 +1,5 @@ +error[E0275]: overflow evaluating the requirement `<() as Recur>::Recur == _` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0275`. diff --git a/tests/ui/type-alias-impl-trait/mututally-recursive-overflow.rs b/tests/ui/type-alias-impl-trait/mututally-recursive-overflow.rs new file mode 100644 index 00000000000..1ccd1b0cbad --- /dev/null +++ b/tests/ui/type-alias-impl-trait/mututally-recursive-overflow.rs @@ -0,0 +1,40 @@ +// edition: 2021 +// build-fail +//~^^ ERROR overflow evaluating the requirement `<() as B>::Assoc == _` + +#![feature(rustc_attrs)] +#![feature(impl_trait_in_assoc_type)] + +#[rustc_coinductive] +trait A { + type Assoc; + + fn test() -> Self::Assoc; +} + +#[rustc_coinductive] +trait B { + type Assoc; + + fn test() -> Self::Assoc; +} + +impl<T: A> B for T { + type Assoc = impl Sized; + + fn test() -> <Self as B>::Assoc { + <T as A>::test() + } +} + +fn main() { + <() as A>::test(); +} + +impl<T: B> A for T { + type Assoc = impl Sized; + + fn test() -> <Self as A>::Assoc { + <T as B>::test() + } +} diff --git a/tests/ui/type-alias-impl-trait/mututally-recursive-overflow.stderr b/tests/ui/type-alias-impl-trait/mututally-recursive-overflow.stderr new file mode 100644 index 00000000000..49c59f7eb37 --- /dev/null +++ b/tests/ui/type-alias-impl-trait/mututally-recursive-overflow.stderr @@ -0,0 +1,5 @@ +error[E0275]: overflow evaluating the requirement `<() as B>::Assoc == _` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0275`. diff --git a/tests/ui/type-alias-impl-trait/nested-tait-hrtb.rs b/tests/ui/type-alias-impl-trait/nested-tait-hrtb.rs index 4a9631a7208..ba705d6f85a 100644 --- a/tests/ui/type-alias-impl-trait/nested-tait-hrtb.rs +++ b/tests/ui/type-alias-impl-trait/nested-tait-hrtb.rs @@ -8,7 +8,7 @@ fn without_lt() -> impl for<'a> Trait<'a, Assoc = WithoutLt> {} //~^ ERROR captures lifetime that does not appear in bounds type WithLt<'a> = impl Sized + 'a; -//~^ ERROR concrete type differs from previous defining opaque type use + fn with_lt() -> impl for<'a> Trait<'a, Assoc = WithLt<'a>> {} //~^ ERROR expected generic lifetime parameter, found `'a` diff --git a/tests/ui/type-alias-impl-trait/nested-tait-hrtb.stderr b/tests/ui/type-alias-impl-trait/nested-tait-hrtb.stderr index 9a783a6d92a..f208730552d 100644 --- a/tests/ui/type-alias-impl-trait/nested-tait-hrtb.stderr +++ b/tests/ui/type-alias-impl-trait/nested-tait-hrtb.stderr @@ -17,19 +17,7 @@ LL | LL | fn with_lt() -> impl for<'a> Trait<'a, Assoc = WithLt<'a>> {} | ^^ -error: concrete type differs from previous defining opaque type use - --> $DIR/nested-tait-hrtb.rs:10:19 - | -LL | type WithLt<'a> = impl Sized + 'a; - | ^^^^^^^^^^^^^^^ expected `&'a str`, got `{type error}` - | -note: previous use here - --> $DIR/nested-tait-hrtb.rs:12:17 - | -LL | fn with_lt() -> impl for<'a> Trait<'a, Assoc = WithLt<'a>> {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -error: aborting due to 3 previous errors +error: aborting due to 2 previous errors Some errors have detailed explanations: E0700, E0792. For more information about an error, try `rustc --explain E0700`. diff --git a/tests/ui/type-alias-impl-trait/rpit_tait_equality_in_canonical_query.rs b/tests/ui/type-alias-impl-trait/rpit_tait_equality_in_canonical_query.rs new file mode 100644 index 00000000000..eefe333da45 --- /dev/null +++ b/tests/ui/type-alias-impl-trait/rpit_tait_equality_in_canonical_query.rs @@ -0,0 +1,25 @@ +//! This tries to prove the APIT's bounds in a canonical query, +//! which doesn't know anything about the defining scope of either +//! opaque type and thus makes a random choice as to which opaque type +//! becomes the hidden type of the other. When we leave the canonical +//! query, we attempt to actually check the defining anchor, but now we +//! have a situation where the RPIT gets constrained outside its anchor. + +// revisions: current next +//[next] compile-flags: -Ztrait-solver=next +// check-pass + +#![feature(type_alias_impl_trait)] + +type Opaque = impl Sized; + +fn get_rpit() -> impl Clone {} + +fn query(_: impl FnOnce() -> Opaque) {} + +fn test() -> Opaque { + query(get_rpit); + get_rpit() +} + +fn main() {} diff --git a/tests/ui/type-alias-impl-trait/variance.rs b/tests/ui/type-alias-impl-trait/variance.rs index eba4816003b..e92cf2513e7 100644 --- a/tests/ui/type-alias-impl-trait/variance.rs +++ b/tests/ui/type-alias-impl-trait/variance.rs @@ -9,42 +9,36 @@ type NotCapturedEarly<'a> = impl Sized; //~ [o] type CapturedEarly<'a> = impl Sized + Captures<'a>; //~ [o] +// TAIT does *not* capture `'b` type NotCapturedLate<'a> = dyn for<'b> Iterator<Item = impl Sized>; //~ [o] -type CapturedLate<'a> = dyn for<'b> Iterator<Item = impl Sized + Captures<'b>>; //~ [o] - -type Captured<'a> = dyn for<'b> Iterator<Item = impl Sized + Captures<'a> + Captures<'b>>; //~ [o] +// TAIT does *not* capture `'b` +type Captured<'a> = dyn for<'b> Iterator<Item = impl Sized + Captures<'a>>; //~ [o] type Bar<'a, 'b: 'b, T> = impl Sized; //~ ERROR [o, o, o] trait Foo<'i> { - type ImplicitCapturedEarly<'a>; - - type ExplicitCaptureEarly<'a>; + type ImplicitCapture<'a>; - type ImplicitCaptureLate<'a>; + type ExplicitCaptureFromHeader<'a>; - type ExplicitCaptureLate<'a>; + type ExplicitCaptureFromGat<'a>; } impl<'i> Foo<'i> for &'i () { - type ImplicitCapturedEarly<'a> = impl Sized; //~ [o, o] + type ImplicitCapture<'a> = impl Sized; //~ [o, o] - type ExplicitCaptureEarly<'a> = impl Sized + Captures<'i>; //~ [o, o] + type ExplicitCaptureFromHeader<'a> = impl Sized + Captures<'i>; //~ [o, o] - type ImplicitCaptureLate<'a> = impl Sized; //~ [o, o] - - type ExplicitCaptureLate<'a> = impl Sized + Captures<'a>; //~ [o, o] + type ExplicitCaptureFromGat<'a> = impl Sized + Captures<'a>; //~ [o, o] } impl<'i> Foo<'i> for () { - type ImplicitCapturedEarly<'a> = impl Sized; //~ [o, o] - - type ExplicitCaptureEarly<'a> = impl Sized + Captures<'i>; //~ [o, o] + type ImplicitCapture<'a> = impl Sized; //~ [o, o] - type ImplicitCaptureLate<'a> = impl Sized; //~ [o, o] + type ExplicitCaptureFromHeader<'a> = impl Sized + Captures<'i>; //~ [o, o] - type ExplicitCaptureLate<'a> = impl Sized + Captures<'a>; //~ [o, o] + type ExplicitCaptureFromGat<'a> = impl Sized + Captures<'a>; //~ [o, o] } fn main() {} diff --git a/tests/ui/type-alias-impl-trait/variance.stderr b/tests/ui/type-alias-impl-trait/variance.stderr index f73cf617a4c..1794447c89a 100644 --- a/tests/ui/type-alias-impl-trait/variance.stderr +++ b/tests/ui/type-alias-impl-trait/variance.stderr @@ -11,22 +11,16 @@ LL | type CapturedEarly<'a> = impl Sized + Captures<'a>; | ^^^^^^^^^^^^^^^^^^^^^^^^^ error: [o] - --> $DIR/variance.rs:12:56 + --> $DIR/variance.rs:13:56 | LL | type NotCapturedLate<'a> = dyn for<'b> Iterator<Item = impl Sized>; | ^^^^^^^^^^ error: [o] - --> $DIR/variance.rs:14:53 - | -LL | type CapturedLate<'a> = dyn for<'b> Iterator<Item = impl Sized + Captures<'b>>; - | ^^^^^^^^^^^^^^^^^^^^^^^^^ - -error: [o] --> $DIR/variance.rs:16:49 | -LL | type Captured<'a> = dyn for<'b> Iterator<Item = impl Sized + Captures<'a> + Captures<'b>>; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | type Captured<'a> = dyn for<'b> Iterator<Item = impl Sized + Captures<'a>>; + | ^^^^^^^^^^^^^^^^^^^^^^^^^ error: [o, o, o] --> $DIR/variance.rs:18:27 @@ -35,52 +29,40 @@ LL | type Bar<'a, 'b: 'b, T> = impl Sized; | ^^^^^^^^^^ error: [o, o] - --> $DIR/variance.rs:31:38 - | -LL | type ImplicitCapturedEarly<'a> = impl Sized; - | ^^^^^^^^^^ - -error: [o, o] - --> $DIR/variance.rs:33:37 - | -LL | type ExplicitCaptureEarly<'a> = impl Sized + Captures<'i>; - | ^^^^^^^^^^^^^^^^^^^^^^^^^ - -error: [o, o] - --> $DIR/variance.rs:35:36 + --> $DIR/variance.rs:29:32 | -LL | type ImplicitCaptureLate<'a> = impl Sized; - | ^^^^^^^^^^ +LL | type ImplicitCapture<'a> = impl Sized; + | ^^^^^^^^^^ error: [o, o] - --> $DIR/variance.rs:37:36 + --> $DIR/variance.rs:31:42 | -LL | type ExplicitCaptureLate<'a> = impl Sized + Captures<'a>; - | ^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | type ExplicitCaptureFromHeader<'a> = impl Sized + Captures<'i>; + | ^^^^^^^^^^^^^^^^^^^^^^^^^ error: [o, o] - --> $DIR/variance.rs:41:38 + --> $DIR/variance.rs:33:39 | -LL | type ImplicitCapturedEarly<'a> = impl Sized; - | ^^^^^^^^^^ +LL | type ExplicitCaptureFromGat<'a> = impl Sized + Captures<'a>; + | ^^^^^^^^^^^^^^^^^^^^^^^^^ error: [o, o] - --> $DIR/variance.rs:43:37 + --> $DIR/variance.rs:37:32 | -LL | type ExplicitCaptureEarly<'a> = impl Sized + Captures<'i>; - | ^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | type ImplicitCapture<'a> = impl Sized; + | ^^^^^^^^^^ error: [o, o] - --> $DIR/variance.rs:45:36 + --> $DIR/variance.rs:39:42 | -LL | type ImplicitCaptureLate<'a> = impl Sized; - | ^^^^^^^^^^ +LL | type ExplicitCaptureFromHeader<'a> = impl Sized + Captures<'i>; + | ^^^^^^^^^^^^^^^^^^^^^^^^^ error: [o, o] - --> $DIR/variance.rs:47:36 + --> $DIR/variance.rs:41:39 | -LL | type ExplicitCaptureLate<'a> = impl Sized + Captures<'a>; - | ^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | type ExplicitCaptureFromGat<'a> = impl Sized + Captures<'a>; + | ^^^^^^^^^^^^^^^^^^^^^^^^^ -error: aborting due to 14 previous errors +error: aborting due to 11 previous errors diff --git a/tests/ui/type/type-arg-out-of-scope.rs b/tests/ui/type/type-arg-out-of-scope.rs index 02aad007707..c36f9904e5d 100644 --- a/tests/ui/type/type-arg-out-of-scope.rs +++ b/tests/ui/type/type-arg-out-of-scope.rs @@ -1,4 +1,4 @@ -// error-pattern:can't use generic parameters from outer function +// error-pattern:can't use generic parameters from outer item fn foo<T>(x: T) { fn bar(f: Box<dyn FnMut(T) -> T>) { } } diff --git a/tests/ui/type/type-arg-out-of-scope.stderr b/tests/ui/type/type-arg-out-of-scope.stderr index 7f18b4510f4..8665001e243 100644 --- a/tests/ui/type/type-arg-out-of-scope.stderr +++ b/tests/ui/type/type-arg-out-of-scope.stderr @@ -1,22 +1,22 @@ -error[E0401]: can't use generic parameters from outer function +error[E0401]: can't use generic parameters from outer item --> $DIR/type-arg-out-of-scope.rs:3:29 | LL | fn foo<T>(x: T) { - | - type parameter from outer function + | - type parameter from outer item LL | fn bar(f: Box<dyn FnMut(T) -> T>) { } - | - ^ use of generic parameter from outer function + | - ^ use of generic parameter from outer item | | - | help: try using a local generic parameter instead: `<T>` + | help: try introducing a local generic parameter here: `<T>` -error[E0401]: can't use generic parameters from outer function +error[E0401]: can't use generic parameters from outer item --> $DIR/type-arg-out-of-scope.rs:3:35 | LL | fn foo<T>(x: T) { - | - type parameter from outer function + | - type parameter from outer item LL | fn bar(f: Box<dyn FnMut(T) -> T>) { } - | - ^ use of generic parameter from outer function + | - ^ use of generic parameter from outer item | | - | help: try using a local generic parameter instead: `<T>` + | help: try introducing a local generic parameter here: `<T>` error: aborting due to 2 previous errors diff --git a/tests/ui/union/projection-as-union-type-error-2.stderr b/tests/ui/union/projection-as-union-type-error-2.stderr index bab226f271d..21f4ea103ad 100644 --- a/tests/ui/union/projection-as-union-type-error-2.stderr +++ b/tests/ui/union/projection-as-union-type-error-2.stderr @@ -4,6 +4,11 @@ error[E0277]: the trait bound `u8: NotImplemented` is not satisfied LL | a: <Foo as Identity>::Identity, | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `NotImplemented` is not implemented for `u8` | +help: this trait has no implementations, consider adding one + --> $DIR/projection-as-union-type-error-2.rs:9:1 + | +LL | trait NotImplemented {} + | ^^^^^^^^^^^^^^^^^^^^ note: required for `u8` to implement `Identity` --> $DIR/projection-as-union-type-error-2.rs:11:25 | diff --git a/tests/ui/union/projection-as-union-type-error.stderr b/tests/ui/union/projection-as-union-type-error.stderr index e4fbe9603ad..2b0241caf98 100644 --- a/tests/ui/union/projection-as-union-type-error.stderr +++ b/tests/ui/union/projection-as-union-type-error.stderr @@ -3,6 +3,12 @@ error[E0277]: the trait bound `u8: Identity` is not satisfied | LL | a: <Foo as Identity>::Identity, | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Identity` is not implemented for `u8` + | +help: this trait has no implementations, consider adding one + --> $DIR/projection-as-union-type-error.rs:6:1 + | +LL | pub trait Identity { + | ^^^^^^^^^^^^^^^^^^ error: aborting due to previous error diff --git a/tests/ui/unreachable-code.rs b/tests/ui/unreachable-code.rs index 28b938edc63..64174db7afb 100644 --- a/tests/ui/unreachable-code.rs +++ b/tests/ui/unreachable-code.rs @@ -2,25 +2,32 @@ #![allow(unused_must_use)] #![allow(dead_code)] - #![allow(path_statements)] #![allow(unreachable_code)] #![allow(unused_variables)] +#![feature(if_let_guard)] -fn id(x: bool) -> bool { x } +fn id(x: bool) -> bool { + x +} fn call_id() { let c = panic!(); id(c); } -fn call_id_2() { id(true) && id(return); } +fn call_id_2() { + id(true) && id(return); +} -fn call_id_3() { id(return) && id(return); } +fn call_id_3() { + id(return) && id(return); +} fn ret_guard() { match 2 { x if (return) => { x; } + x if let true = return => { x; } _ => {} } } diff --git a/tests/ui/unsafe/edition-2024-unsafe_op_in_unsafe_fn.rs b/tests/ui/unsafe/edition-2024-unsafe_op_in_unsafe_fn.rs new file mode 100644 index 00000000000..a192f3445f7 --- /dev/null +++ b/tests/ui/unsafe/edition-2024-unsafe_op_in_unsafe_fn.rs @@ -0,0 +1,17 @@ +// edition: 2024 +// compile-flags: -Zunstable-options +// check-pass + +#![crate_type = "lib"] + +#![deny(unused_unsafe)] + +unsafe fn unsf() {} + +unsafe fn foo() { + unsf(); + //~^ WARN call to unsafe function is unsafe and requires unsafe block + + // no unused_unsafe + unsafe { unsf(); } +} diff --git a/tests/ui/unsafe/edition-2024-unsafe_op_in_unsafe_fn.stderr b/tests/ui/unsafe/edition-2024-unsafe_op_in_unsafe_fn.stderr new file mode 100644 index 00000000000..fbc621f4d0e --- /dev/null +++ b/tests/ui/unsafe/edition-2024-unsafe_op_in_unsafe_fn.stderr @@ -0,0 +1,16 @@ +warning: call to unsafe function is unsafe and requires unsafe block (error E0133) + --> $DIR/edition-2024-unsafe_op_in_unsafe_fn.rs:12:5 + | +LL | unsf(); + | ^^^^^^ call to unsafe function + | + = note: consult the function's documentation for information on how to avoid undefined behavior +note: an unsafe function restricts its caller, but its body is safe by default + --> $DIR/edition-2024-unsafe_op_in_unsafe_fn.rs:11:1 + | +LL | unsafe fn foo() { + | ^^^^^^^^^^^^^^^ + = note: `#[warn(unsafe_op_in_unsafe_fn)]` on by default + +warning: 1 warning emitted + diff --git a/tests/ui/unsized/issue-115809.rs b/tests/ui/unsized/issue-115809.rs new file mode 100644 index 00000000000..ff25365ea50 --- /dev/null +++ b/tests/ui/unsized/issue-115809.rs @@ -0,0 +1,13 @@ +// compile-flags: --emit=link -Zmir-opt-level=2 -Zpolymorphize=on + +fn foo<T>() { + let a: [i32; 0] = []; + match [a[..]] { + //~^ ERROR cannot move a value of type `[i32] + //~| ERROR cannot move out of type `[i32]`, a non-copy slice + [[x]] => {} + _ => (), + } +} + +fn main() {} diff --git a/tests/ui/unsized/issue-115809.stderr b/tests/ui/unsized/issue-115809.stderr new file mode 100644 index 00000000000..a92554b79b9 --- /dev/null +++ b/tests/ui/unsized/issue-115809.stderr @@ -0,0 +1,19 @@ +error[E0161]: cannot move a value of type `[i32]` + --> $DIR/issue-115809.rs:5:12 + | +LL | match [a[..]] { + | ^^^^^ the size of `[i32]` cannot be statically determined + +error[E0508]: cannot move out of type `[i32]`, a non-copy slice + --> $DIR/issue-115809.rs:5:12 + | +LL | match [a[..]] { + | ^^^^^ + | | + | cannot move out of here + | move occurs because value has type `[i32]`, which does not implement the `Copy` trait + +error: aborting due to 2 previous errors + +Some errors have detailed explanations: E0161, E0508. +For more information about an error, try `rustc --explain E0161`. diff --git a/tests/ui/unsized/issue-75707.stderr b/tests/ui/unsized/issue-75707.stderr index 97618ed05ed..aa7f9c78fa8 100644 --- a/tests/ui/unsized/issue-75707.stderr +++ b/tests/ui/unsized/issue-75707.stderr @@ -4,6 +4,11 @@ error[E0277]: the trait bound `MyCall: Callback` is not satisfied LL | f::<dyn Processing<Call = MyCall>>(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Callback` is not implemented for `MyCall` | +help: this trait has no implementations, consider adding one + --> $DIR/issue-75707.rs:1:1 + | +LL | pub trait Callback { + | ^^^^^^^^^^^^^^^^^^ note: required by a bound in `f` --> $DIR/issue-75707.rs:9:9 | diff --git a/tests/ui/wf/hir-wf-canonicalized.stderr b/tests/ui/wf/hir-wf-canonicalized.stderr index 9fd0f9c81eb..21122e37da5 100644 --- a/tests/ui/wf/hir-wf-canonicalized.stderr +++ b/tests/ui/wf/hir-wf-canonicalized.stderr @@ -3,12 +3,24 @@ error[E0277]: the trait bound `Bar<'a, T>: Foo` is not satisfied | LL | callback: Box<dyn Callback<dyn Callback<Bar<'a, T>>>>, | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Foo` is not implemented for `Bar<'a, T>` + | +help: this trait has no implementations, consider adding one + --> $DIR/hir-wf-canonicalized.rs:3:1 + | +LL | trait Foo { + | ^^^^^^^^^ error[E0277]: the trait bound `(dyn Callback<Bar<'a, T>, for<'b, 'c, 'd> Output = ()> + 'static): Foo` is not satisfied --> $DIR/hir-wf-canonicalized.rs:10:15 | LL | callback: Box<dyn Callback<dyn Callback<Bar<'a, T>>>>, | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Foo` is not implemented for `(dyn Callback<Bar<'a, T>, for<'b, 'c, 'd> Output = ()> + 'static)` + | +help: this trait has no implementations, consider adding one + --> $DIR/hir-wf-canonicalized.rs:3:1 + | +LL | trait Foo { + | ^^^^^^^^^ error[E0277]: the size for values of type `(dyn Callback<Bar<'a, T>, for<'b, 'c, 'd> Output = ()> + 'static)` cannot be known at compilation time --> $DIR/hir-wf-canonicalized.rs:10:15 diff --git a/tests/ui/wf/issue-95665.stderr b/tests/ui/wf/issue-95665.stderr index b1cda59a916..f80cd41a4c2 100644 --- a/tests/ui/wf/issue-95665.stderr +++ b/tests/ui/wf/issue-95665.stderr @@ -4,6 +4,11 @@ error[E0277]: the trait bound `u8: Trait` is not satisfied LL | static VAR: Struct<u8>; | ^^^^^^^^^^ the trait `Trait` is not implemented for `u8` | +help: this trait has no implementations, consider adding one + --> $DIR/issue-95665.rs:4:1 + | +LL | pub trait Trait: {} + | ^^^^^^^^^^^^^^^ note: required by a bound in `Struct` --> $DIR/issue-95665.rs:6:22 | diff --git a/tests/ui/wf/wf-complex-assoc-type.stderr b/tests/ui/wf/wf-complex-assoc-type.stderr index ef613e3132d..6a623bec815 100644 --- a/tests/ui/wf/wf-complex-assoc-type.stderr +++ b/tests/ui/wf/wf-complex-assoc-type.stderr @@ -4,6 +4,11 @@ error[E0277]: the trait bound `bool: MyTrait` is not satisfied LL | type MyItem = Option<((AssertMyTrait<bool>, u8))>; | ^^^^^^^^^^^^^^^^^^^ the trait `MyTrait` is not implemented for `bool` | +help: this trait has no implementations, consider adding one + --> $DIR/wf-complex-assoc-type.rs:1:1 + | +LL | trait MyTrait {} + | ^^^^^^^^^^^^^ note: required by a bound in `AssertMyTrait` --> $DIR/wf-complex-assoc-type.rs:2:25 | diff --git a/tests/ui/wf/wf-foreign-fn-decl-ret.stderr b/tests/ui/wf/wf-foreign-fn-decl-ret.stderr index b03023b5fd1..0e93601043a 100644 --- a/tests/ui/wf/wf-foreign-fn-decl-ret.stderr +++ b/tests/ui/wf/wf-foreign-fn-decl-ret.stderr @@ -3,6 +3,12 @@ error[E0277]: the trait bound `(): Foo` is not satisfied | LL | pub fn lint_me() -> <() as Foo>::Assoc; | ^^^^^^^^^^^^^^^^^^ the trait `Foo` is not implemented for `()` + | +help: this trait has no implementations, consider adding one + --> $DIR/wf-foreign-fn-decl-ret.rs:6:1 + | +LL | pub trait Foo { + | ^^^^^^^^^^^^^ error[E0277]: the trait bound `u32: Unsatisfied` is not satisfied --> $DIR/wf-foreign-fn-decl-ret.rs:14:32 @@ -10,6 +16,11 @@ error[E0277]: the trait bound `u32: Unsatisfied` is not satisfied LL | pub fn lint_me_aswell() -> Bar<u32>; | ^^^^^^^^ the trait `Unsatisfied` is not implemented for `u32` | +help: this trait has no implementations, consider adding one + --> $DIR/wf-foreign-fn-decl-ret.rs:1:1 + | +LL | pub trait Unsatisfied {} + | ^^^^^^^^^^^^^^^^^^^^^ note: required by a bound in `Bar` --> $DIR/wf-foreign-fn-decl-ret.rs:4:19 | diff --git a/tests/ui/wf/wf-packed-on-proj-of-type-as-unimpl-trait.stderr b/tests/ui/wf/wf-packed-on-proj-of-type-as-unimpl-trait.stderr index e460cdcd3f3..52f46562c37 100644 --- a/tests/ui/wf/wf-packed-on-proj-of-type-as-unimpl-trait.stderr +++ b/tests/ui/wf/wf-packed-on-proj-of-type-as-unimpl-trait.stderr @@ -3,6 +3,12 @@ error[E0277]: the trait bound `DefaultAllocator: Allocator` is not satisfied | LL | struct Foo(Matrix<<DefaultAllocator as Allocator>::Buffer>); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Allocator` is not implemented for `DefaultAllocator` + | +help: this trait has no implementations, consider adding one + --> $DIR/wf-packed-on-proj-of-type-as-unimpl-trait.rs:23:1 + | +LL | pub trait Allocator { type Buffer; } + | ^^^^^^^^^^^^^^^^^^^ error: aborting due to previous error diff --git a/tests/ui/where-clauses/higher-ranked-fn-type.quiet.stderr b/tests/ui/where-clauses/higher-ranked-fn-type.quiet.stderr index 191a8ca8ebc..29b36f44a4d 100644 --- a/tests/ui/where-clauses/higher-ranked-fn-type.quiet.stderr +++ b/tests/ui/where-clauses/higher-ranked-fn-type.quiet.stderr @@ -4,6 +4,11 @@ error[E0277]: the trait bound `for<'b> fn(&'b ()): Foo` is not satisfied LL | called() | ^^^^^^ the trait `for<'b> Foo` is not implemented for `fn(&'b ())` | +help: this trait has no implementations, consider adding one + --> $DIR/higher-ranked-fn-type.rs:6:1 + | +LL | trait Foo { + | ^^^^^^^^^ note: required by a bound in `called` --> $DIR/higher-ranked-fn-type.rs:12:25 | diff --git a/tests/ui/where-clauses/higher-ranked-fn-type.verbose.stderr b/tests/ui/where-clauses/higher-ranked-fn-type.verbose.stderr index ce409f627be..54afeaa7eda 100644 --- a/tests/ui/where-clauses/higher-ranked-fn-type.verbose.stderr +++ b/tests/ui/where-clauses/higher-ranked-fn-type.verbose.stderr @@ -4,6 +4,11 @@ error[E0277]: the trait bound `for<Region(BrNamed(DefId(0:6 ~ higher_ranked_fn_t LL | called() | ^^^^^^ the trait `for<Region(BrNamed(DefId(0:6 ~ higher_ranked_fn_type[9e51]::called::'b), 'b))> Foo` is not implemented for `fn(&ReLateBound(DebruijnIndex(1), BoundRegion { var: 0, kind: BrNamed(DefId(0:6 ~ higher_ranked_fn_type[9e51]::called::'b), 'b) }) ())` | +help: this trait has no implementations, consider adding one + --> $DIR/higher-ranked-fn-type.rs:6:1 + | +LL | trait Foo { + | ^^^^^^^^^ note: required by a bound in `called` --> $DIR/higher-ranked-fn-type.rs:12:25 | diff --git a/tests/ui/where-clauses/where-clause-method-substituion.stderr b/tests/ui/where-clauses/where-clause-method-substituion.stderr index 8c47ed6d431..2f3b615a13b 100644 --- a/tests/ui/where-clauses/where-clause-method-substituion.stderr +++ b/tests/ui/where-clauses/where-clause-method-substituion.stderr @@ -4,6 +4,11 @@ error[E0277]: the trait bound `X: Foo<X>` is not satisfied LL | 1.method::<X>(); | ^ the trait `Foo<X>` is not implemented for `X` | +help: this trait has no implementations, consider adding one + --> $DIR/where-clause-method-substituion.rs:1:1 + | +LL | trait Foo<T> { + | ^^^^^^^^^^^^ note: required by a bound in `Bar::method` --> $DIR/where-clause-method-substituion.rs:6:34 | |
