diff options
Diffstat (limited to 'tests')
179 files changed, 4347 insertions, 723 deletions
diff --git a/tests/codegen/align-byval-alignment-mismatch.rs b/tests/codegen/align-byval-alignment-mismatch.rs new file mode 100644 index 00000000000..306e3ce1358 --- /dev/null +++ b/tests/codegen/align-byval-alignment-mismatch.rs @@ -0,0 +1,126 @@ +// ignore-tidy-linelength +//@ revisions:i686-linux x86_64-linux + +//@[i686-linux] compile-flags: --target i686-unknown-linux-gnu +//@[i686-linux] needs-llvm-components: x86 +//@[x86_64-linux] compile-flags: --target x86_64-unknown-linux-gnu +//@[x86_64-linux] needs-llvm-components: x86 + +// Tests that we correctly copy arguments into allocas when the alignment of the byval argument +// is different from the alignment of the Rust type. + +// For the following test cases: +// All of the `*_decreases_alignment` functions should codegen to a direct call, since the +// alignment is already sufficient. +// All off the `*_increases_alignment` functions should copy the argument to an alloca +// on i686-unknown-linux-gnu, since the alignment needs to be increased, and should codegen +// to a direct call on x86_64-unknown-linux-gnu, where byval alignment matches Rust alignment. + +#![feature(no_core, lang_items)] +#![crate_type = "lib"] +#![no_std] +#![no_core] +#![allow(non_camel_case_types)] + +#[lang = "sized"] +trait Sized {} +#[lang = "freeze"] +trait Freeze {} +#[lang = "copy"] +trait Copy {} + +// This type has align 1 in Rust, but as a byval argument on i686-linux, it will have align 4. +#[repr(C)] +#[repr(packed)] +struct Align1 { + x: u128, + y: u128, + z: u128, +} + +// This type has align 16 in Rust, but as a byval argument on i686-linux, it will have align 4. +#[repr(C)] +#[repr(align(16))] +struct Align16 { + x: u128, + y: u128, + z: u128, +} + +extern "C" { + fn extern_c_align1(x: Align1); + fn extern_c_align16(x: Align16); +} + +// CHECK-LABEL: @rust_to_c_increases_alignment +#[no_mangle] +pub unsafe fn rust_to_c_increases_alignment(x: Align1) { + // i686-linux: start: + // i686-linux-NEXT: [[ALLOCA:%[0-9a-z]+]] = alloca %Align1, align 4 + // i686-linux-NEXT: call void @llvm.memcpy.{{.+}}(ptr {{.*}}align 4 {{.*}}[[ALLOCA]], ptr {{.*}}align 1 {{.*}}%x + // i686-linux-NEXT: call void @extern_c_align1({{.+}} [[ALLOCA]]) + + // x86_64-linux: start: + // x86_64-linux-NEXT: call void @extern_c_align1 + extern_c_align1(x); +} + +// CHECK-LABEL: @rust_to_c_decreases_alignment +#[no_mangle] +pub unsafe fn rust_to_c_decreases_alignment(x: Align16) { + // CHECK: start: + // CHECK-NEXT: call void @extern_c_align16 + extern_c_align16(x); +} + +extern "Rust" { + fn extern_rust_align1(x: Align1); + fn extern_rust_align16(x: Align16); +} + +// CHECK-LABEL: @c_to_rust_decreases_alignment +#[no_mangle] +pub unsafe extern "C" fn c_to_rust_decreases_alignment(x: Align1) { + // CHECK: start: + // CHECK-NEXT: call void @extern_rust_align1 + extern_rust_align1(x); +} + +// CHECK-LABEL: @c_to_rust_increases_alignment +#[no_mangle] +pub unsafe extern "C" fn c_to_rust_increases_alignment(x: Align16) { + // i686-linux: start: + // i686-linux-NEXT: [[ALLOCA:%[0-9a-z]+]] = alloca %Align16, align 16 + // i686-linux-NEXT: call void @llvm.memcpy.{{.+}}(ptr {{.*}}align 16 {{.*}}[[ALLOCA]], ptr {{.*}}align 4 {{.*}}%0 + // i686-linux-NEXT: call void @extern_rust_align16({{.+}} [[ALLOCA]]) + + // x86_64-linux: start: + // x86_64-linux-NEXT: call void @extern_rust_align16 + extern_rust_align16(x); +} + +extern "Rust" { + fn extern_rust_ref_align1(x: &Align1); + fn extern_rust_ref_align16(x: &Align16); +} + +// CHECK-LABEL: @c_to_rust_ref_decreases_alignment +#[no_mangle] +pub unsafe extern "C" fn c_to_rust_ref_decreases_alignment(x: Align1) { + // CHECK: start: + // CHECK-NEXT: call void @extern_rust_ref_align1 + extern_rust_ref_align1(&x); +} + +// CHECK-LABEL: @c_to_rust_ref_increases_alignment +#[no_mangle] +pub unsafe extern "C" fn c_to_rust_ref_increases_alignment(x: Align16) { + // i686-linux: start: + // i686-linux-NEXT: [[ALLOCA:%[0-9a-z]+]] = alloca %Align16, align 16 + // i686-linux-NEXT: call void @llvm.memcpy.{{.+}}(ptr {{.*}}align 16 {{.*}}[[ALLOCA]], ptr {{.*}}align 4 {{.*}}%0 + // i686-linux-NEXT: call void @extern_rust_ref_align16({{.+}} [[ALLOCA]]) + + // x86_64-linux: start: + // x86_64-linux-NEXT: call void @extern_rust_ref_align16 + extern_rust_ref_align16(&x); +} diff --git a/tests/coverage/branch_generics.cov-map b/tests/coverage/branch_generics.cov-map new file mode 100644 index 00000000000..719e97efad4 --- /dev/null +++ b/tests/coverage/branch_generics.cov-map @@ -0,0 +1,54 @@ +Function name: branch_generics::print_size::<()> +Raw bytes (35): 0x[01, 01, 02, 01, 05, 05, 02, 05, 01, 06, 01, 01, 24, 20, 05, 02, 01, 08, 00, 24, 05, 00, 25, 02, 06, 02, 02, 0c, 02, 06, 07, 03, 01, 00, 02] +Number of files: 1 +- file 0 => global file 1 +Number of expressions: 2 +- expression 0 operands: lhs = Counter(0), rhs = Counter(1) +- expression 1 operands: lhs = Counter(1), rhs = Expression(0, Sub) +Number of file 0 mappings: 5 +- Code(Counter(0)) at (prev + 6, 1) to (start + 1, 36) +- Branch { true: Counter(1), false: Expression(0, Sub) } at (prev + 1, 8) to (start + 0, 36) + true = c1 + false = (c0 - c1) +- Code(Counter(1)) at (prev + 0, 37) to (start + 2, 6) +- Code(Expression(0, Sub)) at (prev + 2, 12) to (start + 2, 6) + = (c0 - c1) +- Code(Expression(1, Add)) at (prev + 3, 1) to (start + 0, 2) + = (c1 + (c0 - c1)) + +Function name: branch_generics::print_size::<u32> +Raw bytes (35): 0x[01, 01, 02, 01, 05, 05, 02, 05, 01, 06, 01, 01, 24, 20, 05, 02, 01, 08, 00, 24, 05, 00, 25, 02, 06, 02, 02, 0c, 02, 06, 07, 03, 01, 00, 02] +Number of files: 1 +- file 0 => global file 1 +Number of expressions: 2 +- expression 0 operands: lhs = Counter(0), rhs = Counter(1) +- expression 1 operands: lhs = Counter(1), rhs = Expression(0, Sub) +Number of file 0 mappings: 5 +- Code(Counter(0)) at (prev + 6, 1) to (start + 1, 36) +- Branch { true: Counter(1), false: Expression(0, Sub) } at (prev + 1, 8) to (start + 0, 36) + true = c1 + false = (c0 - c1) +- Code(Counter(1)) at (prev + 0, 37) to (start + 2, 6) +- Code(Expression(0, Sub)) at (prev + 2, 12) to (start + 2, 6) + = (c0 - c1) +- Code(Expression(1, Add)) at (prev + 3, 1) to (start + 0, 2) + = (c1 + (c0 - c1)) + +Function name: branch_generics::print_size::<u64> +Raw bytes (35): 0x[01, 01, 02, 01, 05, 05, 02, 05, 01, 06, 01, 01, 24, 20, 05, 02, 01, 08, 00, 24, 05, 00, 25, 02, 06, 02, 02, 0c, 02, 06, 07, 03, 01, 00, 02] +Number of files: 1 +- file 0 => global file 1 +Number of expressions: 2 +- expression 0 operands: lhs = Counter(0), rhs = Counter(1) +- expression 1 operands: lhs = Counter(1), rhs = Expression(0, Sub) +Number of file 0 mappings: 5 +- Code(Counter(0)) at (prev + 6, 1) to (start + 1, 36) +- Branch { true: Counter(1), false: Expression(0, Sub) } at (prev + 1, 8) to (start + 0, 36) + true = c1 + false = (c0 - c1) +- Code(Counter(1)) at (prev + 0, 37) to (start + 2, 6) +- Code(Expression(0, Sub)) at (prev + 2, 12) to (start + 2, 6) + = (c0 - c1) +- Code(Expression(1, Add)) at (prev + 3, 1) to (start + 0, 2) + = (c1 + (c0 - c1)) + diff --git a/tests/coverage/branch_generics.coverage b/tests/coverage/branch_generics.coverage new file mode 100644 index 00000000000..e7cec151ce6 --- /dev/null +++ b/tests/coverage/branch_generics.coverage @@ -0,0 +1,62 @@ + LL| |#![feature(coverage_attribute)] + LL| |//@ edition: 2021 + LL| |//@ compile-flags: -Zcoverage-options=branch + LL| |//@ llvm-cov-flags: --show-branches=count + LL| | + LL| 3|fn print_size<T>() { + LL| 3| if std::mem::size_of::<T>() > 4 { + ------------------ + | Branch (LL:8): [True: 0, False: 1] + | Branch (LL:8): [True: 0, False: 1] + | Branch (LL:8): [True: 1, False: 0] + ------------------ + LL| 1| println!("size > 4"); + LL| 2| } else { + LL| 2| println!("size <= 4"); + LL| 2| } + LL| 3|} + ------------------ + | branch_generics::print_size::<()>: + | LL| 1|fn print_size<T>() { + | LL| 1| if std::mem::size_of::<T>() > 4 { + | ------------------ + | | Branch (LL:8): [True: 0, False: 1] + | ------------------ + | LL| 0| println!("size > 4"); + | LL| 1| } else { + | LL| 1| println!("size <= 4"); + | LL| 1| } + | LL| 1|} + ------------------ + | branch_generics::print_size::<u32>: + | LL| 1|fn print_size<T>() { + | LL| 1| if std::mem::size_of::<T>() > 4 { + | ------------------ + | | Branch (LL:8): [True: 0, False: 1] + | ------------------ + | LL| 0| println!("size > 4"); + | LL| 1| } else { + | LL| 1| println!("size <= 4"); + | LL| 1| } + | LL| 1|} + ------------------ + | branch_generics::print_size::<u64>: + | LL| 1|fn print_size<T>() { + | LL| 1| if std::mem::size_of::<T>() > 4 { + | ------------------ + | | Branch (LL:8): [True: 1, False: 0] + | ------------------ + | LL| 1| println!("size > 4"); + | LL| 1| } else { + | LL| 0| println!("size <= 4"); + | LL| 0| } + | LL| 1|} + ------------------ + LL| | + LL| |#[coverage(off)] + LL| |fn main() { + LL| | print_size::<()>(); + LL| | print_size::<u32>(); + LL| | print_size::<u64>(); + LL| |} + diff --git a/tests/coverage/branch_generics.rs b/tests/coverage/branch_generics.rs new file mode 100644 index 00000000000..d870ace7006 --- /dev/null +++ b/tests/coverage/branch_generics.rs @@ -0,0 +1,19 @@ +#![feature(coverage_attribute)] +//@ edition: 2021 +//@ compile-flags: -Zcoverage-options=branch +//@ llvm-cov-flags: --show-branches=count + +fn print_size<T>() { + if std::mem::size_of::<T>() > 4 { + println!("size > 4"); + } else { + println!("size <= 4"); + } +} + +#[coverage(off)] +fn main() { + print_size::<()>(); + print_size::<u32>(); + print_size::<u64>(); +} diff --git a/tests/coverage/branch_guard.cov-map b/tests/coverage/branch_guard.cov-map new file mode 100644 index 00000000000..0b3622f6347 --- /dev/null +++ b/tests/coverage/branch_guard.cov-map @@ -0,0 +1,32 @@ +Function name: branch_guard::branch_match_guard +Raw bytes (85): 0x[01, 01, 06, 19, 0d, 05, 09, 0f, 15, 13, 11, 17, 0d, 05, 09, 0d, 01, 0c, 01, 01, 10, 1d, 03, 0b, 00, 0c, 15, 01, 14, 02, 0a, 0d, 03, 0e, 00, 0f, 19, 00, 14, 00, 19, 20, 0d, 02, 00, 14, 00, 1e, 0d, 00, 1d, 02, 0a, 11, 03, 0e, 00, 0f, 1d, 00, 14, 00, 19, 20, 11, 09, 00, 14, 00, 1e, 11, 00, 1d, 02, 0a, 17, 03, 0e, 02, 0a, 0b, 04, 01, 00, 02] +Number of files: 1 +- file 0 => global file 1 +Number of expressions: 6 +- expression 0 operands: lhs = Counter(6), rhs = Counter(3) +- expression 1 operands: lhs = Counter(1), rhs = Counter(2) +- expression 2 operands: lhs = Expression(3, Add), rhs = Counter(5) +- expression 3 operands: lhs = Expression(4, Add), rhs = Counter(4) +- expression 4 operands: lhs = Expression(5, Add), rhs = Counter(3) +- expression 5 operands: lhs = Counter(1), rhs = Counter(2) +Number of file 0 mappings: 13 +- Code(Counter(0)) at (prev + 12, 1) to (start + 1, 16) +- Code(Counter(7)) at (prev + 3, 11) to (start + 0, 12) +- Code(Counter(5)) at (prev + 1, 20) to (start + 2, 10) +- Code(Counter(3)) at (prev + 3, 14) to (start + 0, 15) +- Code(Counter(6)) at (prev + 0, 20) to (start + 0, 25) +- Branch { true: Counter(3), false: Expression(0, Sub) } at (prev + 0, 20) to (start + 0, 30) + true = c3 + false = (c6 - c3) +- Code(Counter(3)) at (prev + 0, 29) to (start + 2, 10) +- Code(Counter(4)) at (prev + 3, 14) to (start + 0, 15) +- Code(Counter(7)) at (prev + 0, 20) to (start + 0, 25) +- Branch { true: Counter(4), false: Counter(2) } at (prev + 0, 20) to (start + 0, 30) + true = c4 + false = c2 +- Code(Counter(4)) at (prev + 0, 29) to (start + 2, 10) +- Code(Expression(5, Add)) at (prev + 3, 14) to (start + 2, 10) + = (c1 + c2) +- Code(Expression(2, Add)) at (prev + 4, 1) to (start + 0, 2) + = ((((c1 + c2) + c3) + c4) + c5) + diff --git a/tests/coverage/branch_guard.coverage b/tests/coverage/branch_guard.coverage new file mode 100644 index 00000000000..f89b965b5d0 --- /dev/null +++ b/tests/coverage/branch_guard.coverage @@ -0,0 +1,45 @@ + LL| |#![feature(coverage_attribute)] + LL| |//@ edition: 2021 + LL| |//@ compile-flags: -Zcoverage-options=branch + LL| |//@ llvm-cov-flags: --show-branches=count + LL| | + LL| |macro_rules! no_merge { + LL| | () => { + LL| | for _ in 0..1 {} + LL| | }; + LL| |} + LL| | + LL| 4|fn branch_match_guard(x: Option<u32>) { + LL| 4| no_merge!(); + LL| | + LL| 1| match x { + LL| 1| Some(0) => { + LL| 1| println!("zero"); + LL| 1| } + LL| 3| Some(x) if x % 2 == 0 => { + ^2 + ------------------ + | Branch (LL:20): [True: 2, False: 1] + ------------------ + LL| 2| println!("is nonzero and even"); + LL| 2| } + LL| 1| Some(x) if x % 3 == 0 => { + ------------------ + | Branch (LL:20): [True: 1, False: 0] + ------------------ + LL| 1| println!("is nonzero and odd, but divisible by 3"); + LL| 1| } + LL| 0| _ => { + LL| 0| println!("something else"); + LL| 0| } + LL| | } + LL| 4|} + LL| | + LL| |#[coverage(off)] + LL| |fn main() { + LL| | branch_match_guard(Some(0)); + LL| | branch_match_guard(Some(2)); + LL| | branch_match_guard(Some(6)); + LL| | branch_match_guard(Some(3)); + LL| |} + diff --git a/tests/coverage/branch_guard.rs b/tests/coverage/branch_guard.rs new file mode 100644 index 00000000000..fa049e6206d --- /dev/null +++ b/tests/coverage/branch_guard.rs @@ -0,0 +1,37 @@ +#![feature(coverage_attribute)] +//@ edition: 2021 +//@ compile-flags: -Zcoverage-options=branch +//@ llvm-cov-flags: --show-branches=count + +macro_rules! no_merge { + () => { + for _ in 0..1 {} + }; +} + +fn branch_match_guard(x: Option<u32>) { + no_merge!(); + + match x { + Some(0) => { + println!("zero"); + } + Some(x) if x % 2 == 0 => { + println!("is nonzero and even"); + } + Some(x) if x % 3 == 0 => { + println!("is nonzero and odd, but divisible by 3"); + } + _ => { + println!("something else"); + } + } +} + +#[coverage(off)] +fn main() { + branch_match_guard(Some(0)); + branch_match_guard(Some(2)); + branch_match_guard(Some(6)); + branch_match_guard(Some(3)); +} diff --git a/tests/coverage/branch_if.cov-map b/tests/coverage/branch_if.cov-map new file mode 100644 index 00000000000..0dbfd92541b --- /dev/null +++ b/tests/coverage/branch_if.cov-map @@ -0,0 +1,188 @@ +Function name: branch_if::branch_and +Raw bytes (56): 0x[01, 01, 04, 05, 09, 0d, 02, 11, 0f, 0d, 02, 08, 01, 2b, 01, 01, 10, 05, 03, 08, 00, 09, 20, 09, 02, 00, 08, 00, 09, 09, 00, 0d, 00, 0e, 20, 11, 0d, 00, 0d, 00, 0e, 11, 00, 0f, 02, 06, 0f, 02, 0c, 02, 06, 0b, 03, 01, 00, 02] +Number of files: 1 +- file 0 => global file 1 +Number of expressions: 4 +- expression 0 operands: lhs = Counter(1), rhs = Counter(2) +- expression 1 operands: lhs = Counter(3), rhs = Expression(0, Sub) +- expression 2 operands: lhs = Counter(4), rhs = Expression(3, Add) +- expression 3 operands: lhs = Counter(3), rhs = Expression(0, Sub) +Number of file 0 mappings: 8 +- Code(Counter(0)) at (prev + 43, 1) to (start + 1, 16) +- Code(Counter(1)) at (prev + 3, 8) to (start + 0, 9) +- Branch { true: Counter(2), false: Expression(0, Sub) } at (prev + 0, 8) to (start + 0, 9) + true = c2 + false = (c1 - c2) +- Code(Counter(2)) at (prev + 0, 13) to (start + 0, 14) +- Branch { true: Counter(4), false: Counter(3) } at (prev + 0, 13) to (start + 0, 14) + true = c4 + false = c3 +- Code(Counter(4)) at (prev + 0, 15) to (start + 2, 6) +- Code(Expression(3, Add)) at (prev + 2, 12) to (start + 2, 6) + = (c3 + (c1 - c2)) +- Code(Expression(2, Add)) at (prev + 3, 1) to (start + 0, 2) + = (c4 + (c3 + (c1 - c2))) + +Function name: branch_if::branch_not +Raw bytes (224): 0x[01, 01, 29, 05, 09, 09, 02, a3, 01, 0d, 09, 02, a3, 01, 0d, 09, 02, 0d, 9e, 01, a3, 01, 0d, 09, 02, 9b, 01, 11, 0d, 9e, 01, a3, 01, 0d, 09, 02, 9b, 01, 11, 0d, 9e, 01, a3, 01, 0d, 09, 02, 11, 96, 01, 9b, 01, 11, 0d, 9e, 01, a3, 01, 0d, 09, 02, 93, 01, 15, 11, 96, 01, 9b, 01, 11, 0d, 9e, 01, a3, 01, 0d, 09, 02, 93, 01, 15, 11, 96, 01, 9b, 01, 11, 0d, 9e, 01, a3, 01, 0d, 09, 02, 15, 8e, 01, 93, 01, 15, 11, 96, 01, 9b, 01, 11, 0d, 9e, 01, a3, 01, 0d, 09, 02, 12, 01, 0c, 01, 01, 10, 05, 03, 08, 00, 09, 20, 09, 02, 00, 08, 00, 09, 09, 01, 09, 00, 11, 02, 01, 06, 00, 07, a3, 01, 01, 08, 00, 0a, 20, 9e, 01, 0d, 00, 08, 00, 0a, 9e, 01, 00, 0b, 02, 06, 0d, 02, 06, 00, 07, 9b, 01, 01, 08, 00, 0b, 20, 11, 96, 01, 00, 08, 00, 0b, 11, 00, 0c, 02, 06, 96, 01, 02, 06, 00, 07, 93, 01, 01, 08, 00, 0c, 20, 8e, 01, 15, 00, 08, 00, 0c, 8e, 01, 00, 0d, 02, 06, 15, 02, 06, 00, 07, 8b, 01, 01, 01, 00, 02] +Number of files: 1 +- file 0 => global file 1 +Number of expressions: 41 +- expression 0 operands: lhs = Counter(1), rhs = Counter(2) +- expression 1 operands: lhs = Counter(2), rhs = Expression(0, Sub) +- expression 2 operands: lhs = Expression(40, Add), rhs = Counter(3) +- expression 3 operands: lhs = Counter(2), rhs = Expression(0, Sub) +- expression 4 operands: lhs = Expression(40, Add), rhs = Counter(3) +- expression 5 operands: lhs = Counter(2), rhs = Expression(0, Sub) +- expression 6 operands: lhs = Counter(3), rhs = Expression(39, Sub) +- expression 7 operands: lhs = Expression(40, Add), rhs = Counter(3) +- expression 8 operands: lhs = Counter(2), rhs = Expression(0, Sub) +- expression 9 operands: lhs = Expression(38, Add), rhs = Counter(4) +- expression 10 operands: lhs = Counter(3), rhs = Expression(39, Sub) +- expression 11 operands: lhs = Expression(40, Add), rhs = Counter(3) +- expression 12 operands: lhs = Counter(2), rhs = Expression(0, Sub) +- expression 13 operands: lhs = Expression(38, Add), rhs = Counter(4) +- expression 14 operands: lhs = Counter(3), rhs = Expression(39, Sub) +- expression 15 operands: lhs = Expression(40, Add), rhs = Counter(3) +- expression 16 operands: lhs = Counter(2), rhs = Expression(0, Sub) +- expression 17 operands: lhs = Counter(4), rhs = Expression(37, Sub) +- expression 18 operands: lhs = Expression(38, Add), rhs = Counter(4) +- expression 19 operands: lhs = Counter(3), rhs = Expression(39, Sub) +- expression 20 operands: lhs = Expression(40, Add), rhs = Counter(3) +- expression 21 operands: lhs = Counter(2), rhs = Expression(0, Sub) +- expression 22 operands: lhs = Expression(36, Add), rhs = Counter(5) +- expression 23 operands: lhs = Counter(4), rhs = Expression(37, Sub) +- expression 24 operands: lhs = Expression(38, Add), rhs = Counter(4) +- expression 25 operands: lhs = Counter(3), rhs = Expression(39, Sub) +- expression 26 operands: lhs = Expression(40, Add), rhs = Counter(3) +- expression 27 operands: lhs = Counter(2), rhs = Expression(0, Sub) +- expression 28 operands: lhs = Expression(36, Add), rhs = Counter(5) +- expression 29 operands: lhs = Counter(4), rhs = Expression(37, Sub) +- expression 30 operands: lhs = Expression(38, Add), rhs = Counter(4) +- expression 31 operands: lhs = Counter(3), rhs = Expression(39, Sub) +- expression 32 operands: lhs = Expression(40, Add), rhs = Counter(3) +- expression 33 operands: lhs = Counter(2), rhs = Expression(0, Sub) +- expression 34 operands: lhs = Counter(5), rhs = Expression(35, Sub) +- expression 35 operands: lhs = Expression(36, Add), rhs = Counter(5) +- expression 36 operands: lhs = Counter(4), rhs = Expression(37, Sub) +- expression 37 operands: lhs = Expression(38, Add), rhs = Counter(4) +- expression 38 operands: lhs = Counter(3), rhs = Expression(39, Sub) +- expression 39 operands: lhs = Expression(40, Add), rhs = Counter(3) +- expression 40 operands: lhs = Counter(2), rhs = Expression(0, Sub) +Number of file 0 mappings: 18 +- Code(Counter(0)) at (prev + 12, 1) to (start + 1, 16) +- Code(Counter(1)) at (prev + 3, 8) to (start + 0, 9) +- Branch { true: Counter(2), false: Expression(0, Sub) } at (prev + 0, 8) to (start + 0, 9) + true = c2 + false = (c1 - c2) +- Code(Counter(2)) at (prev + 1, 9) to (start + 0, 17) +- Code(Expression(0, Sub)) at (prev + 1, 6) to (start + 0, 7) + = (c1 - c2) +- Code(Expression(40, Add)) at (prev + 1, 8) to (start + 0, 10) + = (c2 + (c1 - c2)) +- Branch { true: Expression(39, Sub), false: Counter(3) } at (prev + 0, 8) to (start + 0, 10) + true = ((c2 + (c1 - c2)) - c3) + false = c3 +- Code(Expression(39, Sub)) at (prev + 0, 11) to (start + 2, 6) + = ((c2 + (c1 - c2)) - c3) +- Code(Counter(3)) at (prev + 2, 6) to (start + 0, 7) +- Code(Expression(38, Add)) at (prev + 1, 8) to (start + 0, 11) + = (c3 + ((c2 + (c1 - c2)) - c3)) +- Branch { true: Counter(4), false: Expression(37, Sub) } at (prev + 0, 8) to (start + 0, 11) + true = c4 + false = ((c3 + ((c2 + (c1 - c2)) - c3)) - c4) +- Code(Counter(4)) at (prev + 0, 12) to (start + 2, 6) +- Code(Expression(37, Sub)) at (prev + 2, 6) to (start + 0, 7) + = ((c3 + ((c2 + (c1 - c2)) - c3)) - c4) +- Code(Expression(36, Add)) at (prev + 1, 8) to (start + 0, 12) + = (c4 + ((c3 + ((c2 + (c1 - c2)) - c3)) - c4)) +- Branch { true: Expression(35, Sub), false: Counter(5) } at (prev + 0, 8) to (start + 0, 12) + true = ((c4 + ((c3 + ((c2 + (c1 - c2)) - c3)) - c4)) - c5) + false = c5 +- Code(Expression(35, Sub)) at (prev + 0, 13) to (start + 2, 6) + = ((c4 + ((c3 + ((c2 + (c1 - c2)) - c3)) - c4)) - c5) +- Code(Counter(5)) at (prev + 2, 6) to (start + 0, 7) +- Code(Expression(34, Add)) at (prev + 1, 1) to (start + 0, 2) + = (c5 + ((c4 + ((c3 + ((c2 + (c1 - c2)) - c3)) - c4)) - c5)) + +Function name: branch_if::branch_not_as +Raw bytes (124): 0x[01, 01, 16, 05, 09, 09, 02, 57, 0d, 09, 02, 57, 0d, 09, 02, 0d, 52, 57, 0d, 09, 02, 4f, 11, 0d, 52, 57, 0d, 09, 02, 4f, 11, 0d, 52, 57, 0d, 09, 02, 11, 4a, 4f, 11, 0d, 52, 57, 0d, 09, 02, 0e, 01, 1d, 01, 01, 10, 05, 03, 08, 00, 14, 20, 02, 09, 00, 08, 00, 14, 02, 00, 15, 02, 06, 09, 02, 06, 00, 07, 57, 01, 08, 00, 15, 20, 0d, 52, 00, 08, 00, 15, 0d, 00, 16, 02, 06, 52, 02, 06, 00, 07, 4f, 01, 08, 00, 16, 20, 4a, 11, 00, 08, 00, 16, 4a, 00, 17, 02, 06, 11, 02, 06, 00, 07, 47, 01, 01, 00, 02] +Number of files: 1 +- file 0 => global file 1 +Number of expressions: 22 +- expression 0 operands: lhs = Counter(1), rhs = Counter(2) +- expression 1 operands: lhs = Counter(2), rhs = Expression(0, Sub) +- expression 2 operands: lhs = Expression(21, Add), rhs = Counter(3) +- expression 3 operands: lhs = Counter(2), rhs = Expression(0, Sub) +- expression 4 operands: lhs = Expression(21, Add), rhs = Counter(3) +- expression 5 operands: lhs = Counter(2), rhs = Expression(0, Sub) +- expression 6 operands: lhs = Counter(3), rhs = Expression(20, Sub) +- expression 7 operands: lhs = Expression(21, Add), rhs = Counter(3) +- expression 8 operands: lhs = Counter(2), rhs = Expression(0, Sub) +- expression 9 operands: lhs = Expression(19, Add), rhs = Counter(4) +- expression 10 operands: lhs = Counter(3), rhs = Expression(20, Sub) +- expression 11 operands: lhs = Expression(21, Add), rhs = Counter(3) +- expression 12 operands: lhs = Counter(2), rhs = Expression(0, Sub) +- expression 13 operands: lhs = Expression(19, Add), rhs = Counter(4) +- expression 14 operands: lhs = Counter(3), rhs = Expression(20, Sub) +- expression 15 operands: lhs = Expression(21, Add), rhs = Counter(3) +- expression 16 operands: lhs = Counter(2), rhs = Expression(0, Sub) +- expression 17 operands: lhs = Counter(4), rhs = Expression(18, Sub) +- expression 18 operands: lhs = Expression(19, Add), rhs = Counter(4) +- expression 19 operands: lhs = Counter(3), rhs = Expression(20, Sub) +- expression 20 operands: lhs = Expression(21, Add), rhs = Counter(3) +- expression 21 operands: lhs = Counter(2), rhs = Expression(0, Sub) +Number of file 0 mappings: 14 +- Code(Counter(0)) at (prev + 29, 1) to (start + 1, 16) +- Code(Counter(1)) at (prev + 3, 8) to (start + 0, 20) +- Branch { true: Expression(0, Sub), false: Counter(2) } at (prev + 0, 8) to (start + 0, 20) + true = (c1 - c2) + false = c2 +- Code(Expression(0, Sub)) at (prev + 0, 21) to (start + 2, 6) + = (c1 - c2) +- Code(Counter(2)) at (prev + 2, 6) to (start + 0, 7) +- Code(Expression(21, Add)) at (prev + 1, 8) to (start + 0, 21) + = (c2 + (c1 - c2)) +- Branch { true: Counter(3), false: Expression(20, Sub) } at (prev + 0, 8) to (start + 0, 21) + true = c3 + false = ((c2 + (c1 - c2)) - c3) +- Code(Counter(3)) at (prev + 0, 22) to (start + 2, 6) +- Code(Expression(20, Sub)) at (prev + 2, 6) to (start + 0, 7) + = ((c2 + (c1 - c2)) - c3) +- Code(Expression(19, Add)) at (prev + 1, 8) to (start + 0, 22) + = (c3 + ((c2 + (c1 - c2)) - c3)) +- Branch { true: Expression(18, Sub), false: Counter(4) } at (prev + 0, 8) to (start + 0, 22) + true = ((c3 + ((c2 + (c1 - c2)) - c3)) - c4) + false = c4 +- Code(Expression(18, Sub)) at (prev + 0, 23) to (start + 2, 6) + = ((c3 + ((c2 + (c1 - c2)) - c3)) - c4) +- Code(Counter(4)) at (prev + 2, 6) to (start + 0, 7) +- Code(Expression(17, Add)) at (prev + 1, 1) to (start + 0, 2) + = (c4 + ((c3 + ((c2 + (c1 - c2)) - c3)) - c4)) + +Function name: branch_if::branch_or +Raw bytes (56): 0x[01, 01, 04, 05, 09, 09, 0d, 0f, 11, 09, 0d, 08, 01, 35, 01, 01, 10, 05, 03, 08, 00, 09, 20, 09, 02, 00, 08, 00, 09, 02, 00, 0d, 00, 0e, 20, 0d, 11, 00, 0d, 00, 0e, 0f, 00, 0f, 02, 06, 11, 02, 0c, 02, 06, 0b, 03, 01, 00, 02] +Number of files: 1 +- file 0 => global file 1 +Number of expressions: 4 +- expression 0 operands: lhs = Counter(1), rhs = Counter(2) +- expression 1 operands: lhs = Counter(2), rhs = Counter(3) +- expression 2 operands: lhs = Expression(3, Add), rhs = Counter(4) +- expression 3 operands: lhs = Counter(2), rhs = Counter(3) +Number of file 0 mappings: 8 +- Code(Counter(0)) at (prev + 53, 1) to (start + 1, 16) +- Code(Counter(1)) at (prev + 3, 8) to (start + 0, 9) +- Branch { true: Counter(2), false: Expression(0, Sub) } at (prev + 0, 8) to (start + 0, 9) + true = c2 + false = (c1 - c2) +- Code(Expression(0, Sub)) at (prev + 0, 13) to (start + 0, 14) + = (c1 - c2) +- Branch { true: Counter(3), false: Counter(4) } at (prev + 0, 13) to (start + 0, 14) + true = c3 + false = c4 +- Code(Expression(3, Add)) at (prev + 0, 15) to (start + 2, 6) + = (c2 + c3) +- Code(Counter(4)) at (prev + 2, 12) to (start + 2, 6) +- Code(Expression(2, Add)) at (prev + 3, 1) to (start + 0, 2) + = ((c2 + c3) + c4) + diff --git a/tests/coverage/branch_if.coverage b/tests/coverage/branch_if.coverage new file mode 100644 index 00000000000..2a9a408b16a --- /dev/null +++ b/tests/coverage/branch_if.coverage @@ -0,0 +1,115 @@ + LL| |#![feature(coverage_attribute)] + LL| |//@ edition: 2021 + LL| |//@ compile-flags: -Zcoverage-options=branch + LL| |//@ llvm-cov-flags: --show-branches=count + LL| | + LL| |macro_rules! no_merge { + LL| | () => { + LL| | for _ in 0..1 {} + LL| | }; + LL| |} + LL| | + LL| 3|fn branch_not(a: bool) { + LL| 3| no_merge!(); + LL| | + LL| 3| if a { + ------------------ + | Branch (LL:8): [True: 2, False: 1] + ------------------ + LL| 2| say("a") + LL| 1| } + LL| 3| if !a { + ------------------ + | Branch (LL:8): [True: 1, False: 2] + ------------------ + LL| 1| say("not a"); + LL| 2| } + LL| 3| if !!a { + ------------------ + | Branch (LL:8): [True: 2, False: 1] + ------------------ + LL| 2| say("not not a"); + LL| 2| } + ^1 + LL| 3| if !!!a { + ------------------ + | Branch (LL:8): [True: 1, False: 2] + ------------------ + LL| 1| say("not not not a"); + LL| 2| } + LL| 3|} + LL| | + LL| 3|fn branch_not_as(a: bool) { + LL| 3| no_merge!(); + LL| | + LL| 3| if !(a as bool) { + ------------------ + | Branch (LL:8): [True: 1, False: 2] + ------------------ + LL| 1| say("not (a as bool)"); + LL| 2| } + LL| 3| if !!(a as bool) { + ------------------ + | Branch (LL:8): [True: 2, False: 1] + ------------------ + LL| 2| say("not not (a as bool)"); + LL| 2| } + ^1 + LL| 3| if !!!(a as bool) { + ------------------ + | Branch (LL:8): [True: 1, False: 2] + ------------------ + LL| 1| say("not not (a as bool)"); + LL| 2| } + LL| 3|} + LL| | + LL| 15|fn branch_and(a: bool, b: bool) { + LL| 15| no_merge!(); + LL| | + LL| 15| if a && b { + ^12 + ------------------ + | Branch (LL:8): [True: 12, False: 3] + | Branch (LL:13): [True: 8, False: 4] + ------------------ + LL| 8| say("both"); + LL| 8| } else { + LL| 7| say("not both"); + LL| 7| } + LL| 15|} + LL| | + LL| 15|fn branch_or(a: bool, b: bool) { + LL| 15| no_merge!(); + LL| | + LL| 15| if a || b { + ^3 + ------------------ + | Branch (LL:8): [True: 12, False: 3] + | Branch (LL:13): [True: 2, False: 1] + ------------------ + LL| 14| say("either"); + LL| 14| } else { + LL| 1| say("neither"); + LL| 1| } + LL| 15|} + LL| | + LL| |#[coverage(off)] + LL| |fn say(message: &str) { + LL| | core::hint::black_box(message); + LL| |} + LL| | + LL| |#[coverage(off)] + LL| |fn main() { + LL| | for a in [false, true, true] { + LL| | branch_not(a); + LL| | branch_not_as(a); + LL| | } + LL| | + LL| | for a in [false, true, true, true, true] { + LL| | for b in [false, true, true] { + LL| | branch_and(a, b); + LL| | branch_or(a, b); + LL| | } + LL| | } + LL| |} + diff --git a/tests/coverage/branch_if.rs b/tests/coverage/branch_if.rs new file mode 100644 index 00000000000..151eede75bb --- /dev/null +++ b/tests/coverage/branch_if.rs @@ -0,0 +1,81 @@ +#![feature(coverage_attribute)] +//@ edition: 2021 +//@ compile-flags: -Zcoverage-options=branch +//@ llvm-cov-flags: --show-branches=count + +macro_rules! no_merge { + () => { + for _ in 0..1 {} + }; +} + +fn branch_not(a: bool) { + no_merge!(); + + if a { + say("a") + } + if !a { + say("not a"); + } + if !!a { + say("not not a"); + } + if !!!a { + say("not not not a"); + } +} + +fn branch_not_as(a: bool) { + no_merge!(); + + if !(a as bool) { + say("not (a as bool)"); + } + if !!(a as bool) { + say("not not (a as bool)"); + } + if !!!(a as bool) { + say("not not (a as bool)"); + } +} + +fn branch_and(a: bool, b: bool) { + no_merge!(); + + if a && b { + say("both"); + } else { + say("not both"); + } +} + +fn branch_or(a: bool, b: bool) { + no_merge!(); + + if a || b { + say("either"); + } else { + say("neither"); + } +} + +#[coverage(off)] +fn say(message: &str) { + core::hint::black_box(message); +} + +#[coverage(off)] +fn main() { + for a in [false, true, true] { + branch_not(a); + branch_not_as(a); + } + + for a in [false, true, true, true, true] { + for b in [false, true, true] { + branch_and(a, b); + branch_or(a, b); + } + } +} diff --git a/tests/coverage/branch_while.cov-map b/tests/coverage/branch_while.cov-map new file mode 100644 index 00000000000..d5f54f1abea --- /dev/null +++ b/tests/coverage/branch_while.cov-map @@ -0,0 +1,98 @@ +Function name: branch_while::while_cond +Raw bytes (42): 0x[01, 01, 03, 05, 09, 03, 09, 03, 09, 06, 01, 0c, 01, 01, 10, 05, 03, 09, 00, 12, 03, 01, 0b, 00, 10, 20, 09, 0a, 00, 0b, 00, 10, 09, 00, 11, 02, 06, 0a, 03, 01, 00, 02] +Number of files: 1 +- file 0 => global file 1 +Number of expressions: 3 +- expression 0 operands: lhs = Counter(1), rhs = Counter(2) +- expression 1 operands: lhs = Expression(0, Add), rhs = Counter(2) +- expression 2 operands: lhs = Expression(0, Add), rhs = Counter(2) +Number of file 0 mappings: 6 +- Code(Counter(0)) at (prev + 12, 1) to (start + 1, 16) +- Code(Counter(1)) at (prev + 3, 9) to (start + 0, 18) +- Code(Expression(0, Add)) at (prev + 1, 11) to (start + 0, 16) + = (c1 + c2) +- Branch { true: Counter(2), false: Expression(2, Sub) } at (prev + 0, 11) to (start + 0, 16) + true = c2 + false = ((c1 + c2) - c2) +- Code(Counter(2)) at (prev + 0, 17) to (start + 2, 6) +- Code(Expression(2, Sub)) at (prev + 3, 1) to (start + 0, 2) + = ((c1 + c2) - c2) + +Function name: branch_while::while_cond_not +Raw bytes (42): 0x[01, 01, 03, 05, 09, 03, 09, 03, 09, 06, 01, 15, 01, 01, 10, 05, 03, 09, 00, 12, 03, 01, 0b, 00, 14, 20, 09, 0a, 00, 0b, 00, 14, 09, 00, 15, 02, 06, 0a, 03, 01, 00, 02] +Number of files: 1 +- file 0 => global file 1 +Number of expressions: 3 +- expression 0 operands: lhs = Counter(1), rhs = Counter(2) +- expression 1 operands: lhs = Expression(0, Add), rhs = Counter(2) +- expression 2 operands: lhs = Expression(0, Add), rhs = Counter(2) +Number of file 0 mappings: 6 +- Code(Counter(0)) at (prev + 21, 1) to (start + 1, 16) +- Code(Counter(1)) at (prev + 3, 9) to (start + 0, 18) +- Code(Expression(0, Add)) at (prev + 1, 11) to (start + 0, 20) + = (c1 + c2) +- Branch { true: Counter(2), false: Expression(2, Sub) } at (prev + 0, 11) to (start + 0, 20) + true = c2 + false = ((c1 + c2) - c2) +- Code(Counter(2)) at (prev + 0, 21) to (start + 2, 6) +- Code(Expression(2, Sub)) at (prev + 3, 1) to (start + 0, 2) + = ((c1 + c2) - c2) + +Function name: branch_while::while_op_and +Raw bytes (56): 0x[01, 01, 04, 05, 09, 03, 0d, 03, 0d, 11, 0d, 08, 01, 1e, 01, 01, 10, 05, 03, 09, 01, 12, 03, 02, 0b, 00, 10, 20, 0a, 0d, 00, 0b, 00, 10, 0a, 00, 14, 00, 19, 20, 09, 11, 00, 14, 00, 19, 09, 00, 1a, 03, 06, 0f, 04, 01, 00, 02] +Number of files: 1 +- file 0 => global file 1 +Number of expressions: 4 +- expression 0 operands: lhs = Counter(1), rhs = Counter(2) +- expression 1 operands: lhs = Expression(0, Add), rhs = Counter(3) +- expression 2 operands: lhs = Expression(0, Add), rhs = Counter(3) +- expression 3 operands: lhs = Counter(4), rhs = Counter(3) +Number of file 0 mappings: 8 +- Code(Counter(0)) at (prev + 30, 1) to (start + 1, 16) +- Code(Counter(1)) at (prev + 3, 9) to (start + 1, 18) +- Code(Expression(0, Add)) at (prev + 2, 11) to (start + 0, 16) + = (c1 + c2) +- Branch { true: Expression(2, Sub), false: Counter(3) } at (prev + 0, 11) to (start + 0, 16) + true = ((c1 + c2) - c3) + false = c3 +- Code(Expression(2, Sub)) at (prev + 0, 20) to (start + 0, 25) + = ((c1 + c2) - c3) +- Branch { true: Counter(2), false: Counter(4) } at (prev + 0, 20) to (start + 0, 25) + true = c2 + false = c4 +- Code(Counter(2)) at (prev + 0, 26) to (start + 3, 6) +- Code(Expression(3, Add)) at (prev + 4, 1) to (start + 0, 2) + = (c4 + c3) + +Function name: branch_while::while_op_or +Raw bytes (66): 0x[01, 01, 09, 05, 1b, 09, 0d, 03, 09, 03, 09, 22, 0d, 03, 09, 09, 0d, 22, 0d, 03, 09, 08, 01, 29, 01, 01, 10, 05, 03, 09, 01, 12, 03, 02, 0b, 00, 10, 20, 09, 22, 00, 0b, 00, 10, 22, 00, 14, 00, 19, 20, 0d, 1e, 00, 14, 00, 19, 1b, 00, 1a, 03, 06, 1e, 04, 01, 00, 02] +Number of files: 1 +- file 0 => global file 1 +Number of expressions: 9 +- expression 0 operands: lhs = Counter(1), rhs = Expression(6, Add) +- expression 1 operands: lhs = Counter(2), rhs = Counter(3) +- expression 2 operands: lhs = Expression(0, Add), rhs = Counter(2) +- expression 3 operands: lhs = Expression(0, Add), rhs = Counter(2) +- expression 4 operands: lhs = Expression(8, Sub), rhs = Counter(3) +- expression 5 operands: lhs = Expression(0, Add), rhs = Counter(2) +- expression 6 operands: lhs = Counter(2), rhs = Counter(3) +- expression 7 operands: lhs = Expression(8, Sub), rhs = Counter(3) +- expression 8 operands: lhs = Expression(0, Add), rhs = Counter(2) +Number of file 0 mappings: 8 +- Code(Counter(0)) at (prev + 41, 1) to (start + 1, 16) +- Code(Counter(1)) at (prev + 3, 9) to (start + 1, 18) +- Code(Expression(0, Add)) at (prev + 2, 11) to (start + 0, 16) + = (c1 + (c2 + c3)) +- Branch { true: Counter(2), false: Expression(8, Sub) } at (prev + 0, 11) to (start + 0, 16) + true = c2 + false = ((c1 + (c2 + c3)) - c2) +- Code(Expression(8, Sub)) at (prev + 0, 20) to (start + 0, 25) + = ((c1 + (c2 + c3)) - c2) +- Branch { true: Counter(3), false: Expression(7, Sub) } at (prev + 0, 20) to (start + 0, 25) + true = c3 + false = (((c1 + (c2 + c3)) - c2) - c3) +- Code(Expression(6, Add)) at (prev + 0, 26) to (start + 3, 6) + = (c2 + c3) +- Code(Expression(7, Sub)) at (prev + 4, 1) to (start + 0, 2) + = (((c1 + (c2 + c3)) - c2) - c3) + diff --git a/tests/coverage/branch_while.coverage b/tests/coverage/branch_while.coverage new file mode 100644 index 00000000000..8d9a6c3bc68 --- /dev/null +++ b/tests/coverage/branch_while.coverage @@ -0,0 +1,74 @@ + LL| |#![feature(coverage_attribute)] + LL| |//@ edition: 2021 + LL| |//@ compile-flags: -Zcoverage-options=branch + LL| |//@ llvm-cov-flags: --show-branches=count + LL| | + LL| |macro_rules! no_merge { + LL| | () => { + LL| | for _ in 0..1 {} + LL| | }; + LL| |} + LL| | + LL| 1|fn while_cond() { + LL| 1| no_merge!(); + LL| | + LL| 1| let mut a = 8; + LL| 9| while a > 0 { + ------------------ + | Branch (LL:11): [True: 8, False: 1] + ------------------ + LL| 8| a -= 1; + LL| 8| } + LL| 1|} + LL| | + LL| 1|fn while_cond_not() { + LL| 1| no_merge!(); + LL| | + LL| 1| let mut a = 8; + LL| 9| while !(a == 0) { + ------------------ + | Branch (LL:11): [True: 8, False: 1] + ------------------ + LL| 8| a -= 1; + LL| 8| } + LL| 1|} + LL| | + LL| 1|fn while_op_and() { + LL| 1| no_merge!(); + LL| | + LL| 1| let mut a = 8; + LL| 1| let mut b = 4; + LL| 5| while a > 0 && b > 0 { + ------------------ + | Branch (LL:11): [True: 5, False: 0] + | Branch (LL:20): [True: 4, False: 1] + ------------------ + LL| 4| a -= 1; + LL| 4| b -= 1; + LL| 4| } + LL| 1|} + LL| | + LL| 1|fn while_op_or() { + LL| 1| no_merge!(); + LL| | + LL| 1| let mut a = 4; + LL| 1| let mut b = 8; + LL| 9| while a > 0 || b > 0 { + ^5 + ------------------ + | Branch (LL:11): [True: 4, False: 5] + | Branch (LL:20): [True: 4, False: 1] + ------------------ + LL| 8| a -= 1; + LL| 8| b -= 1; + LL| 8| } + LL| 1|} + LL| | + LL| |#[coverage(off)] + LL| |fn main() { + LL| | while_cond(); + LL| | while_cond_not(); + LL| | while_op_and(); + LL| | while_op_or(); + LL| |} + diff --git a/tests/coverage/branch_while.rs b/tests/coverage/branch_while.rs new file mode 100644 index 00000000000..507815fbecb --- /dev/null +++ b/tests/coverage/branch_while.rs @@ -0,0 +1,58 @@ +#![feature(coverage_attribute)] +//@ edition: 2021 +//@ compile-flags: -Zcoverage-options=branch +//@ llvm-cov-flags: --show-branches=count + +macro_rules! no_merge { + () => { + for _ in 0..1 {} + }; +} + +fn while_cond() { + no_merge!(); + + let mut a = 8; + while a > 0 { + a -= 1; + } +} + +fn while_cond_not() { + no_merge!(); + + let mut a = 8; + while !(a == 0) { + a -= 1; + } +} + +fn while_op_and() { + no_merge!(); + + let mut a = 8; + let mut b = 4; + while a > 0 && b > 0 { + a -= 1; + b -= 1; + } +} + +fn while_op_or() { + no_merge!(); + + let mut a = 4; + let mut b = 8; + while a > 0 || b > 0 { + a -= 1; + b -= 1; + } +} + +#[coverage(off)] +fn main() { + while_cond(); + while_cond_not(); + while_op_and(); + while_op_or(); +} 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 38a3965f0c5..12c1b389fb3 100644 --- a/tests/run-make/issue-88756-default-output/output-default.stdout +++ b/tests/run-make/issue-88756-default-output/output-default.stdout @@ -147,6 +147,8 @@ Options: --test-builder PATH The rustc-like binary to use as the test builder + --test-builder-wrapper PATH + Wrapper program to pass test-builder and arguments --check Run rustdoc checks --generate-redirect-map Generate JSON file at the top level instead of diff --git a/tests/run-make/pdb-alt-path/Makefile b/tests/run-make/pdb-alt-path/Makefile new file mode 100644 index 00000000000..7a0ae3bf2ef --- /dev/null +++ b/tests/run-make/pdb-alt-path/Makefile @@ -0,0 +1,20 @@ +include ../tools.mk + +# only-windows-msvc + +all: + # Test that we don't have the full path to the PDB file in the binary + $(RUSTC) main.rs -g --crate-name my_crate_name --crate-type bin -Cforce-frame-pointers + $(CGREP) "my_crate_name.pdb" < $(TMPDIR)/my_crate_name.exe + $(CGREP) -v "\\my_crate_name.pdb" < $(TMPDIR)/my_crate_name.exe + + # Test that backtraces still can find debuginfo by checking that they contain symbol names and + # source locations. + $(TMPDIR)/my_crate_name.exe &> $(TMPDIR)/backtrace.txt + $(CGREP) "my_crate_name::fn_in_backtrace" < $(TMPDIR)/backtrace.txt + $(CGREP) "main.rs:15" < $(TMPDIR)/backtrace.txt + + # Test that explicitly passed `-Clink-arg=/PDBALTPATH:...` is respected + $(RUSTC) main.rs -g --crate-name my_crate_name --crate-type bin -Clink-arg=/PDBALTPATH:abcdefg.pdb -Cforce-frame-pointers + $(CGREP) "abcdefg.pdb" < $(TMPDIR)/my_crate_name.exe + $(CGREP) -v "my_crate_name.pdb" < $(TMPDIR)/my_crate_name.exe diff --git a/tests/run-make/pdb-alt-path/main.rs b/tests/run-make/pdb-alt-path/main.rs new file mode 100644 index 00000000000..d38d540fbc2 --- /dev/null +++ b/tests/run-make/pdb-alt-path/main.rs @@ -0,0 +1,24 @@ +// The various #[inline(never)] annotations and std::hint::black_box calls are +// an attempt to make unwinding as non-flaky as possible on i686-pc-windows-msvc. + +#[inline(never)] +fn generate_backtrace(x: &u32) { + std::hint::black_box(x); + let bt = std::backtrace::Backtrace::force_capture(); + println!("{}", bt); + std::hint::black_box(x); +} + +#[inline(never)] +fn fn_in_backtrace(x: &u32) { + std::hint::black_box(x); + generate_backtrace(x); + std::hint::black_box(x); +} + +fn main() { + let x = &41; + std::hint::black_box(x); + fn_in_backtrace(x); + std::hint::black_box(x); +} diff --git a/tests/rustdoc-js-std/parser-errors.js b/tests/rustdoc-js-std/parser-errors.js index 16d171260da..ffd169812b6 100644 --- a/tests/rustdoc-js-std/parser-errors.js +++ b/tests/rustdoc-js-std/parser-errors.js @@ -114,7 +114,7 @@ const PARSED = [ original: "(p -> p", returned: [], userQuery: "(p -> p", - error: "Unexpected `-` after `(`", + error: "Unclosed `(`", }, { query: "::a::b", @@ -195,7 +195,7 @@ const PARSED = [ original: "a (b:", returned: [], userQuery: "a (b:", - error: "Expected `,`, `:` or `->`, found `(`", + error: "Unclosed `(`", }, { query: "_:", @@ -330,7 +330,7 @@ const PARSED = [ original: 'a<->', returned: [], userQuery: 'a<->', - error: 'Unexpected `-` after `<`', + error: 'Unclosed `<`', }, { query: "a<a>:", @@ -357,7 +357,16 @@ const PARSED = [ original: "a,:", returned: [], userQuery: "a,:", - error: 'Unexpected `,` in type filter (before `:`)', + error: 'Expected type filter before `:`', + }, + { + query: "a!:", + elems: [], + foundElems: 0, + original: "a!:", + returned: [], + userQuery: "a!:", + error: 'Unexpected `!` in type filter (before `:`)', }, { query: " a<> :", @@ -366,7 +375,7 @@ const PARSED = [ original: "a<> :", returned: [], userQuery: "a<> :", - error: 'Unexpected `<` in type filter (before `:`)', + error: 'Expected `,`, `:` or `->` after `>`, found `:`', }, { query: "mod : :", diff --git a/tests/rustdoc-js-std/parser-hof.js b/tests/rustdoc-js-std/parser-hof.js new file mode 100644 index 00000000000..0b99c45b7a9 --- /dev/null +++ b/tests/rustdoc-js-std/parser-hof.js @@ -0,0 +1,712 @@ +const PARSED = [ + // ML-style HOF + { + query: "(-> F<P>)", + elems: [{ + name: "->", + fullPath: ["->"], + pathWithoutLast: [], + pathLast: "->", + generics: [], + bindings: [ + [ + "output", + [{ + name: "f", + fullPath: ["f"], + pathWithoutLast: [], + pathLast: "f", + generics: [ + { + name: "p", + fullPath: ["p"], + pathWithoutLast: [], + pathLast: "p", + generics: [], + }, + ], + typeFilter: -1, + }], + ], + ], + typeFilter: -1, + }], + foundElems: 1, + original: "(-> F<P>)", + returned: [], + userQuery: "(-> f<p>)", + error: null, + }, + { + query: "(-> P)", + elems: [{ + name: "->", + fullPath: ["->"], + pathWithoutLast: [], + pathLast: "->", + generics: [], + bindings: [ + [ + "output", + [{ + name: "p", + fullPath: ["p"], + pathWithoutLast: [], + pathLast: "p", + generics: [], + typeFilter: -1, + }], + ], + ], + typeFilter: -1, + }], + foundElems: 1, + original: "(-> P)", + returned: [], + userQuery: "(-> p)", + error: null, + }, + { + query: "(->,a)", + elems: [{ + name: "->", + fullPath: ["->"], + pathWithoutLast: [], + pathLast: "->", + generics: [], + bindings: [ + [ + "output", + [{ + name: "a", + fullPath: ["a"], + pathWithoutLast: [], + pathLast: "a", + generics: [], + typeFilter: -1, + }], + ], + ], + typeFilter: -1, + }], + foundElems: 1, + original: "(->,a)", + returned: [], + userQuery: "(->,a)", + error: null, + }, + { + query: "(F<P> ->)", + elems: [{ + name: "->", + fullPath: ["->"], + pathWithoutLast: [], + pathLast: "->", + generics: [{ + name: "f", + fullPath: ["f"], + pathWithoutLast: [], + pathLast: "f", + generics: [ + { + name: "p", + fullPath: ["p"], + pathWithoutLast: [], + pathLast: "p", + generics: [], + }, + ], + typeFilter: -1, + }], + bindings: [ + [ + "output", + [], + ], + ], + typeFilter: -1, + }], + foundElems: 1, + original: "(F<P> ->)", + returned: [], + userQuery: "(f<p> ->)", + error: null, + }, + { + query: "(P ->)", + elems: [{ + name: "->", + fullPath: ["->"], + pathWithoutLast: [], + pathLast: "->", + generics: [{ + name: "p", + fullPath: ["p"], + pathWithoutLast: [], + pathLast: "p", + generics: [], + typeFilter: -1, + }], + bindings: [ + [ + "output", + [], + ], + ], + typeFilter: -1, + }], + foundElems: 1, + original: "(P ->)", + returned: [], + userQuery: "(p ->)", + error: null, + }, + { + query: "(,a->)", + elems: [{ + name: "->", + fullPath: ["->"], + pathWithoutLast: [], + pathLast: "->", + generics: [{ + name: "a", + fullPath: ["a"], + pathWithoutLast: [], + pathLast: "a", + generics: [], + typeFilter: -1, + }], + bindings: [ + [ + "output", + [], + ], + ], + typeFilter: -1, + }], + foundElems: 1, + original: "(,a->)", + returned: [], + userQuery: "(,a->)", + error: null, + }, + { + query: "(aaaaa->a)", + elems: [{ + name: "->", + fullPath: ["->"], + pathWithoutLast: [], + pathLast: "->", + generics: [{ + name: "aaaaa", + fullPath: ["aaaaa"], + pathWithoutLast: [], + pathLast: "aaaaa", + generics: [], + typeFilter: -1, + }], + bindings: [ + [ + "output", + [{ + name: "a", + fullPath: ["a"], + pathWithoutLast: [], + pathLast: "a", + generics: [], + typeFilter: -1, + }], + ], + ], + typeFilter: -1, + }], + foundElems: 1, + original: "(aaaaa->a)", + returned: [], + userQuery: "(aaaaa->a)", + error: null, + }, + { + query: "(aaaaa, b -> a)", + elems: [{ + name: "->", + fullPath: ["->"], + pathWithoutLast: [], + pathLast: "->", + generics: [ + { + name: "aaaaa", + fullPath: ["aaaaa"], + pathWithoutLast: [], + pathLast: "aaaaa", + generics: [], + typeFilter: -1, + }, + { + name: "b", + fullPath: ["b"], + pathWithoutLast: [], + pathLast: "b", + generics: [], + typeFilter: -1, + }, + ], + bindings: [ + [ + "output", + [{ + name: "a", + fullPath: ["a"], + pathWithoutLast: [], + pathLast: "a", + generics: [], + typeFilter: -1, + }], + ], + ], + typeFilter: -1, + }], + foundElems: 1, + original: "(aaaaa, b -> a)", + returned: [], + userQuery: "(aaaaa, b -> a)", + error: null, + }, + { + query: "primitive:(aaaaa, b -> a)", + elems: [{ + name: "->", + fullPath: ["->"], + pathWithoutLast: [], + pathLast: "->", + generics: [ + { + name: "aaaaa", + fullPath: ["aaaaa"], + pathWithoutLast: [], + pathLast: "aaaaa", + generics: [], + typeFilter: -1, + }, + { + name: "b", + fullPath: ["b"], + pathWithoutLast: [], + pathLast: "b", + generics: [], + typeFilter: -1, + }, + ], + bindings: [ + [ + "output", + [{ + name: "a", + fullPath: ["a"], + pathWithoutLast: [], + pathLast: "a", + generics: [], + typeFilter: -1, + }], + ], + ], + typeFilter: 1, + }], + foundElems: 1, + original: "primitive:(aaaaa, b -> a)", + returned: [], + userQuery: "primitive:(aaaaa, b -> a)", + error: null, + }, + { + query: "x, trait:(aaaaa, b -> a)", + elems: [ + { + name: "x", + fullPath: ["x"], + pathWithoutLast: [], + pathLast: "x", + generics: [], + typeFilter: -1, + }, + { + name: "->", + fullPath: ["->"], + pathWithoutLast: [], + pathLast: "->", + generics: [ + { + name: "aaaaa", + fullPath: ["aaaaa"], + pathWithoutLast: [], + pathLast: "aaaaa", + generics: [], + typeFilter: -1, + }, + { + name: "b", + fullPath: ["b"], + pathWithoutLast: [], + pathLast: "b", + generics: [], + typeFilter: -1, + }, + ], + bindings: [ + [ + "output", + [{ + name: "a", + fullPath: ["a"], + pathWithoutLast: [], + pathLast: "a", + generics: [], + typeFilter: -1, + }], + ], + ], + typeFilter: 10, + } + ], + foundElems: 2, + original: "x, trait:(aaaaa, b -> a)", + returned: [], + userQuery: "x, trait:(aaaaa, b -> a)", + error: null, + }, + // Rust-style HOF + { + query: "Fn () -> F<P>", + elems: [{ + name: "fn", + fullPath: ["fn"], + pathWithoutLast: [], + pathLast: "fn", + generics: [], + bindings: [ + [ + "output", + [{ + name: "f", + fullPath: ["f"], + pathWithoutLast: [], + pathLast: "f", + generics: [ + { + name: "p", + fullPath: ["p"], + pathWithoutLast: [], + pathLast: "p", + generics: [], + }, + ], + typeFilter: -1, + }], + ], + ], + typeFilter: -1, + }], + foundElems: 1, + original: "Fn () -> F<P>", + returned: [], + userQuery: "fn () -> f<p>", + error: null, + }, + { + query: "FnMut() -> P", + elems: [{ + name: "fnmut", + fullPath: ["fnmut"], + pathWithoutLast: [], + pathLast: "fnmut", + generics: [], + bindings: [ + [ + "output", + [{ + name: "p", + fullPath: ["p"], + pathWithoutLast: [], + pathLast: "p", + generics: [], + typeFilter: -1, + }], + ], + ], + typeFilter: -1, + }], + foundElems: 1, + original: "FnMut() -> P", + returned: [], + userQuery: "fnmut() -> p", + error: null, + }, + { + query: "(FnMut() -> P)", + elems: [{ + name: "fnmut", + fullPath: ["fnmut"], + pathWithoutLast: [], + pathLast: "fnmut", + generics: [], + bindings: [ + [ + "output", + [{ + name: "p", + fullPath: ["p"], + pathWithoutLast: [], + pathLast: "p", + generics: [], + typeFilter: -1, + }], + ], + ], + typeFilter: -1, + }], + foundElems: 1, + original: "(FnMut() -> P)", + returned: [], + userQuery: "(fnmut() -> p)", + error: null, + }, + { + query: "Fn(F<P>)", + elems: [{ + name: "fn", + fullPath: ["fn"], + pathWithoutLast: [], + pathLast: "fn", + generics: [{ + name: "f", + fullPath: ["f"], + pathWithoutLast: [], + pathLast: "f", + generics: [ + { + name: "p", + fullPath: ["p"], + pathWithoutLast: [], + pathLast: "p", + generics: [], + }, + ], + typeFilter: -1, + }], + bindings: [ + [ + "output", + [], + ], + ], + typeFilter: -1, + }], + foundElems: 1, + original: "Fn(F<P>)", + returned: [], + userQuery: "fn(f<p>)", + error: null, + }, + { + query: "primitive:fnonce(aaaaa, b) -> a", + elems: [{ + name: "fnonce", + fullPath: ["fnonce"], + pathWithoutLast: [], + pathLast: "fnonce", + generics: [ + { + name: "aaaaa", + fullPath: ["aaaaa"], + pathWithoutLast: [], + pathLast: "aaaaa", + generics: [], + typeFilter: -1, + }, + { + name: "b", + fullPath: ["b"], + pathWithoutLast: [], + pathLast: "b", + generics: [], + typeFilter: -1, + }, + ], + bindings: [ + [ + "output", + [{ + name: "a", + fullPath: ["a"], + pathWithoutLast: [], + pathLast: "a", + generics: [], + typeFilter: -1, + }], + ], + ], + typeFilter: 1, + }], + foundElems: 1, + original: "primitive:fnonce(aaaaa, b) -> a", + returned: [], + userQuery: "primitive:fnonce(aaaaa, b) -> a", + error: null, + }, + { + query: "primitive:fnonce(aaaaa, keyword:b) -> trait:a", + elems: [{ + name: "fnonce", + fullPath: ["fnonce"], + pathWithoutLast: [], + pathLast: "fnonce", + generics: [ + { + name: "aaaaa", + fullPath: ["aaaaa"], + pathWithoutLast: [], + pathLast: "aaaaa", + generics: [], + typeFilter: -1, + }, + { + name: "b", + fullPath: ["b"], + pathWithoutLast: [], + pathLast: "b", + generics: [], + typeFilter: 0, + }, + ], + bindings: [ + [ + "output", + [{ + name: "a", + fullPath: ["a"], + pathWithoutLast: [], + pathLast: "a", + generics: [], + typeFilter: 10, + }], + ], + ], + typeFilter: 1, + }], + foundElems: 1, + original: "primitive:fnonce(aaaaa, keyword:b) -> trait:a", + returned: [], + userQuery: "primitive:fnonce(aaaaa, keyword:b) -> trait:a", + error: null, + }, + { + query: "x, trait:fn(aaaaa, b -> a)", + elems: [ + { + name: "x", + fullPath: ["x"], + pathWithoutLast: [], + pathLast: "x", + generics: [], + typeFilter: -1, + }, + { + name: "fn", + fullPath: ["fn"], + pathWithoutLast: [], + pathLast: "fn", + generics: [ + { + name: "->", + fullPath: ["->"], + pathWithoutLast: [], + pathLast: "->", + generics: [ + { + name: "aaaaa", + fullPath: ["aaaaa"], + pathWithoutLast: [], + pathLast: "aaaaa", + generics: [], + typeFilter: -1, + }, + { + name: "b", + fullPath: ["b"], + pathWithoutLast: [], + pathLast: "b", + generics: [], + typeFilter: -1, + }, + ], + bindings: [ + [ + "output", + [{ + name: "a", + fullPath: ["a"], + pathWithoutLast: [], + pathLast: "a", + generics: [], + typeFilter: -1, + }], + ], + ], + typeFilter: -1, + }, + ], + bindings: [ + [ + "output", + [], + ] + ], + typeFilter: 10, + } + ], + foundElems: 2, + original: "x, trait:fn(aaaaa, b -> a)", + returned: [], + userQuery: "x, trait:fn(aaaaa, b -> a)", + error: null, + }, + { + query: 'a,b(c)', + elems: [ + { + name: "a", + fullPath: ["a"], + pathWithoutLast: [], + pathLast: "a", + generics: [], + typeFilter: -1, + }, + { + name: "b", + fullPath: ["b"], + pathWithoutLast: [], + pathLast: "b", + generics: [{ + name: "c", + fullPath: ["c"], + pathWithoutLast: [], + pathLast: "c", + generics: [], + typeFilter: -1, + }], + bindings: [ + [ + "output", + [], + ] + ], + typeFilter: -1, + } + ], + foundElems: 2, + original: "a,b(c)", + returned: [], + userQuery: "a,b(c)", + error: null, + }, +]; diff --git a/tests/rustdoc-js-std/parser-weird-queries.js b/tests/rustdoc-js-std/parser-weird-queries.js index 26b8c32d680..499b82a3469 100644 --- a/tests/rustdoc-js-std/parser-weird-queries.js +++ b/tests/rustdoc-js-std/parser-weird-queries.js @@ -38,15 +38,6 @@ const PARSED = [ error: null, }, { - query: 'a,b(c)', - elems: [], - foundElems: 0, - original: "a,b(c)", - returned: [], - userQuery: "a,b(c)", - error: "Expected `,`, `:` or `->`, found `(`", - }, - { query: 'aaa,a', elems: [ { diff --git a/tests/rustdoc-js/auxiliary/interner.rs b/tests/rustdoc-js/auxiliary/interner.rs new file mode 100644 index 00000000000..c95029be9f0 --- /dev/null +++ b/tests/rustdoc-js/auxiliary/interner.rs @@ -0,0 +1,245 @@ +#![feature(associated_type_defaults)] + +use std::cmp::Ord; +use std::fmt::{Debug, Formatter}; +use std::hash::Hash; +use std::ops::ControlFlow; + +pub trait Interner: Sized { + type DefId: Copy + Debug + Hash + Ord; + type AdtDef: Copy + Debug + Hash + Ord; + type GenericArgs: Copy + + DebugWithInfcx<Self> + + Hash + + Ord + + IntoIterator<Item = Self::GenericArg>; + type GenericArg: Copy + DebugWithInfcx<Self> + Hash + Ord; + type Term: Copy + Debug + Hash + Ord; + type Binder<T: TypeVisitable<Self>>: BoundVars<Self> + TypeSuperVisitable<Self>; + type BoundVars: IntoIterator<Item = Self::BoundVar>; + type BoundVar; + type CanonicalVars: Copy + Debug + Hash + Eq + IntoIterator<Item = CanonicalVarInfo<Self>>; + type Ty: Copy + + DebugWithInfcx<Self> + + Hash + + Ord + + Into<Self::GenericArg> + + IntoKind<Kind = TyKind<Self>> + + TypeSuperVisitable<Self> + + Flags + + Ty<Self>; + type Tys: Copy + Debug + Hash + Ord + IntoIterator<Item = Self::Ty>; + type AliasTy: Copy + DebugWithInfcx<Self> + Hash + Ord; + type ParamTy: Copy + Debug + Hash + Ord; + type BoundTy: Copy + Debug + Hash + Ord; + type PlaceholderTy: Copy + Debug + Hash + Ord + PlaceholderLike; + type ErrorGuaranteed: Copy + Debug + Hash + Ord; + type BoundExistentialPredicates: Copy + DebugWithInfcx<Self> + Hash + Ord; + type PolyFnSig: Copy + DebugWithInfcx<Self> + Hash + Ord; + type AllocId: Copy + Debug + Hash + Ord; + type Const: Copy + + DebugWithInfcx<Self> + + Hash + + Ord + + Into<Self::GenericArg> + + IntoKind<Kind = ConstKind<Self>> + + ConstTy<Self> + + TypeSuperVisitable<Self> + + Flags + + Const<Self>; + type AliasConst: Copy + DebugWithInfcx<Self> + Hash + Ord; + type PlaceholderConst: Copy + Debug + Hash + Ord + PlaceholderLike; + type ParamConst: Copy + Debug + Hash + Ord; + type BoundConst: Copy + Debug + Hash + Ord; + type ValueConst: Copy + Debug + Hash + Ord; + type ExprConst: Copy + DebugWithInfcx<Self> + Hash + Ord; + type Region: Copy + + DebugWithInfcx<Self> + + Hash + + Ord + + Into<Self::GenericArg> + + IntoKind<Kind = RegionKind<Self>> + + Flags + + Region<Self>; + type EarlyParamRegion: Copy + Debug + Hash + Ord; + type LateParamRegion: Copy + Debug + Hash + Ord; + type BoundRegion: Copy + Debug + Hash + Ord; + type InferRegion: Copy + DebugWithInfcx<Self> + Hash + Ord; + type PlaceholderRegion: Copy + Debug + Hash + Ord + PlaceholderLike; + type Predicate: Copy + Debug + Hash + Eq + TypeSuperVisitable<Self> + Flags; + type TraitPredicate: Copy + Debug + Hash + Eq; + type RegionOutlivesPredicate: Copy + Debug + Hash + Eq; + type TypeOutlivesPredicate: Copy + Debug + Hash + Eq; + type ProjectionPredicate: Copy + Debug + Hash + Eq; + type NormalizesTo: Copy + Debug + Hash + Eq; + type SubtypePredicate: Copy + Debug + Hash + Eq; + type CoercePredicate: Copy + Debug + Hash + Eq; + type ClosureKind: Copy + Debug + Hash + Eq; + + // Required method + fn mk_canonical_var_infos( + self, + infos: &[CanonicalVarInfo<Self>] + ) -> Self::CanonicalVars; +} + +pub trait DebugWithInfcx<I: Interner>: Debug { + // Required method + fn fmt<Infcx: InferCtxtLike<Interner = I>>( + this: WithInfcx<'_, Infcx, &Self>, + f: &mut Formatter<'_> + ) -> std::fmt::Result; +} + +pub trait TypeVisitable<I: Interner>: Debug + Clone { + // Required method + fn visit_with<V: TypeVisitor<I>>(&self, visitor: &mut V) -> V::Result; +} + +pub trait BoundVars<I: Interner> { + // Required methods + fn bound_vars(&self) -> I::BoundVars; + fn has_no_bound_vars(&self) -> bool; +} + +pub trait TypeSuperVisitable<I: Interner>: TypeVisitable<I> { + // Required method + fn super_visit_with<V: TypeVisitor<I>>(&self, visitor: &mut V) -> V::Result; +} + +pub struct CanonicalVarInfo<I: Interner> { + pub kind: CanonicalVarKind<I>, +} + +pub struct CanonicalVarKind<I>(std::marker::PhantomData<I>); + +pub struct TyKind<I>(std::marker::PhantomData<I>); + +pub trait IntoKind { + type Kind; + + // Required method + fn kind(self) -> Self::Kind; +} +pub trait Flags { + // Required methods + fn flags(&self) -> TypeFlags; + fn outer_exclusive_binder(&self) -> DebruijnIndex; +} +pub struct TypeFlags; + +pub trait Ty<I: Interner<Ty = Self>> { + // Required method + fn new_anon_bound( + interner: I, + debruijn: DebruijnIndex, + var: BoundVar + ) -> Self; +} + +pub trait PlaceholderLike { + // Required methods + fn universe(self) -> UniverseIndex; + fn var(self) -> BoundVar; + fn with_updated_universe(self, ui: UniverseIndex) -> Self; + fn new(ui: UniverseIndex, var: BoundVar) -> Self; +} + +pub struct UniverseIndex; + +pub struct BoundVar; + +pub struct ConstKind<I>(std::marker::PhantomData<I>); +pub trait Const<I: Interner<Const = Self>> { + // Required method + fn new_anon_bound( + interner: I, + debruijn: DebruijnIndex, + var: BoundVar, + ty: I::Ty + ) -> Self; +} + +pub trait ConstTy<I: Interner> { + // Required method + fn ty(self) -> I::Ty; +} + +pub struct DebruijnIndex; + +pub struct RegionKind<I>(std::marker::PhantomData<I>); +pub trait Region<I: Interner<Region = Self>> { + // Required method + fn new_anon_bound( + interner: I, + debruijn: DebruijnIndex, + var: BoundVar + ) -> Self; +} + +pub trait TypeVisitor<I: Interner>: Sized { + type Result: VisitorResult = (); + + // Provided methods + fn visit_binder<T: TypeVisitable<I>>( + &mut self, + t: &I::Binder<T> + ) -> Self::Result { unimplemented!() } + fn visit_ty(&mut self, t: I::Ty) -> Self::Result { unimplemented!() } + fn visit_region(&mut self, _r: I::Region) -> Self::Result { unimplemented!() } + fn visit_const(&mut self, c: I::Const) -> Self::Result { unimplemented!() } + fn visit_predicate(&mut self, p: I::Predicate) -> Self::Result { unimplemented!() } +} + +pub trait VisitorResult { + type Residual; + + // Required methods + fn output() -> Self; + fn from_residual(residual: Self::Residual) -> Self; + fn from_branch(b: ControlFlow<Self::Residual>) -> Self; + fn branch(self) -> ControlFlow<Self::Residual>; +} + +impl VisitorResult for () { + type Residual = (); + fn output() -> Self {} + fn from_residual(_: Self::Residual) -> Self {} + fn from_branch(_: ControlFlow<Self::Residual>) -> Self {} + fn branch(self) -> ControlFlow<Self::Residual> { ControlFlow::Continue(()) } +} + +pub struct WithInfcx<'a, Infcx: InferCtxtLike, T> { + pub data: T, + pub infcx: &'a Infcx, +} + +pub trait InferCtxtLike { + type Interner: Interner; + + // Required methods + fn interner(&self) -> Self::Interner; + fn universe_of_ty(&self, ty: TyVid) -> Option<UniverseIndex>; + fn root_ty_var(&self, vid: TyVid) -> TyVid; + fn probe_ty_var( + &self, + vid: TyVid + ) -> Option<<Self::Interner as Interner>::Ty>; + fn universe_of_lt( + &self, + lt: <Self::Interner as Interner>::InferRegion + ) -> Option<UniverseIndex>; + fn opportunistic_resolve_lt_var( + &self, + vid: <Self::Interner as Interner>::InferRegion + ) -> Option<<Self::Interner as Interner>::Region>; + fn universe_of_ct(&self, ct: ConstVid) -> Option<UniverseIndex>; + fn root_ct_var(&self, vid: ConstVid) -> ConstVid; + fn probe_ct_var( + &self, + vid: ConstVid + ) -> Option<<Self::Interner as Interner>::Const>; +} + +pub struct TyVid; +pub struct ConstVid; diff --git a/tests/rustdoc-js/hof.js b/tests/rustdoc-js/hof.js new file mode 100644 index 00000000000..5e6c9d83c7c --- /dev/null +++ b/tests/rustdoc-js/hof.js @@ -0,0 +1,176 @@ +// exact-check + +const EXPECTED = [ + // not a HOF query + { + 'query': 'u32 -> !', + 'others': [], + }, + + // ML-style higher-order function notation + { + 'query': 'bool, (u32 -> !) -> ()', + 'others': [ + {"path": "hof", "name": "fn_ptr"}, + ], + }, + { + 'query': 'u8, (u32 -> !) -> ()', + 'others': [ + {"path": "hof", "name": "fn_once"}, + ], + }, + { + 'query': 'i8, (u32 -> !) -> ()', + 'others': [ + {"path": "hof", "name": "fn_mut"}, + ], + }, + { + 'query': 'char, (u32 -> !) -> ()', + 'others': [ + {"path": "hof", "name": "fn_"}, + ], + }, + { + 'query': '(first<u32> -> !) -> ()', + 'others': [ + {"path": "hof", "name": "fn_ptr"}, + ], + }, + { + 'query': '(second<u32> -> !) -> ()', + 'others': [ + {"path": "hof", "name": "fn_once"}, + ], + }, + { + 'query': '(third<u32> -> !) -> ()', + 'others': [ + {"path": "hof", "name": "fn_mut"}, + ], + }, + { + 'query': '(u32 -> !) -> ()', + 'others': [ + {"path": "hof", "name": "fn_"}, + {"path": "hof", "name": "fn_ptr"}, + {"path": "hof", "name": "fn_mut"}, + {"path": "hof", "name": "fn_once"}, + ], + }, + { + 'query': '(str, str -> i8) -> ()', + 'others': [ + {"path": "hof", "name": "multiple"}, + ], + }, + { + 'query': '(str ->) -> ()', + 'others': [ + {"path": "hof", "name": "multiple"}, + ], + }, + { + 'query': '(-> i8) -> ()', + 'others': [ + {"path": "hof", "name": "multiple"}, + ], + }, + { + 'query': '(str -> str) -> ()', + // params and return are not the same + 'others': [], + }, + { + 'query': '(i8 ->) -> ()', + // params and return are not the same + 'others': [], + }, + { + 'query': '(-> str) -> ()', + // params and return are not the same + 'others': [], + }, + + // Rust-style higher-order function notation + { + 'query': 'bool, fn(u32) -> ! -> ()', + 'others': [ + {"path": "hof", "name": "fn_ptr"}, + ], + }, + { + 'query': 'u8, fnonce(u32) -> ! -> ()', + 'others': [ + {"path": "hof", "name": "fn_once"}, + ], + }, + { + 'query': 'u8, fn(u32) -> ! -> ()', + // fnonce != fn + 'others': [], + }, + { + 'query': 'i8, fnmut(u32) -> ! -> ()', + 'others': [ + {"path": "hof", "name": "fn_mut"}, + ], + }, + { + 'query': 'i8, fn(u32) -> ! -> ()', + // fnmut != fn + 'others': [], + }, + { + 'query': 'char, fn(u32) -> ! -> ()', + 'others': [ + {"path": "hof", "name": "fn_"}, + ], + }, + { + 'query': 'char, fnmut(u32) -> ! -> ()', + // fn != fnmut + 'others': [], + }, + { + 'query': 'fn(first<u32>) -> ! -> ()', + 'others': [ + {"path": "hof", "name": "fn_ptr"}, + ], + }, + { + 'query': 'fnonce(second<u32>) -> ! -> ()', + 'others': [ + {"path": "hof", "name": "fn_once"}, + ], + }, + { + 'query': 'fnmut(third<u32>) -> ! -> ()', + 'others': [ + {"path": "hof", "name": "fn_mut"}, + ], + }, + { + 'query': 'fn(u32) -> ! -> ()', + 'others': [ + // fn matches primitive:fn and trait:Fn + {"path": "hof", "name": "fn_"}, + {"path": "hof", "name": "fn_ptr"}, + ], + }, + { + 'query': 'trait:fn(u32) -> ! -> ()', + 'others': [ + // fn matches primitive:fn and trait:Fn + {"path": "hof", "name": "fn_"}, + ], + }, + { + 'query': 'primitive:fn(u32) -> ! -> ()', + 'others': [ + // fn matches primitive:fn and trait:Fn + {"path": "hof", "name": "fn_ptr"}, + ], + }, +]; diff --git a/tests/rustdoc-js/hof.rs b/tests/rustdoc-js/hof.rs new file mode 100644 index 00000000000..4d2c6e331ca --- /dev/null +++ b/tests/rustdoc-js/hof.rs @@ -0,0 +1,12 @@ +#![feature(never_type)] + +pub struct First<T>(T); +pub struct Second<T>(T); +pub struct Third<T>(T); + +pub fn fn_ptr(_: fn (First<u32>) -> !, _: bool) {} +pub fn fn_once(_: impl FnOnce (Second<u32>) -> !, _: u8) {} +pub fn fn_mut(_: impl FnMut (Third<u32>) -> !, _: i8) {} +pub fn fn_(_: impl Fn (u32) -> !, _: char) {} + +pub fn multiple(_: impl Fn(&'static str, &'static str) -> i8) {} diff --git a/tests/rustdoc-js/looks-like-rustc-interner.js b/tests/rustdoc-js/looks-like-rustc-interner.js new file mode 100644 index 00000000000..a4806d23499 --- /dev/null +++ b/tests/rustdoc-js/looks-like-rustc-interner.js @@ -0,0 +1,9 @@ +// https://github.com/rust-lang/rust/pull/122247 +// exact-check + +const EXPECTED = { + 'query': 'canonicalvarinfo, intoiterator -> intoiterator', + 'others': [ + { 'path': 'looks_like_rustc_interner::Interner', 'name': 'mk_canonical_var_infos' }, + ], +}; diff --git a/tests/rustdoc-js/looks-like-rustc-interner.rs b/tests/rustdoc-js/looks-like-rustc-interner.rs new file mode 100644 index 00000000000..f304e28d952 --- /dev/null +++ b/tests/rustdoc-js/looks-like-rustc-interner.rs @@ -0,0 +1,5 @@ +//@ aux-crate:interner=interner.rs +// https://github.com/rust-lang/rust/pull/122247 +extern crate interner; +#[doc(inline)] +pub use interner::*; diff --git a/tests/rustdoc/display-hidden-items.rs b/tests/rustdoc/display-hidden-items.rs index 76124554767..901ca17d4d2 100644 --- a/tests/rustdoc/display-hidden-items.rs +++ b/tests/rustdoc/display-hidden-items.rs @@ -5,19 +5,22 @@ #![crate_name = "foo"] // @has 'foo/index.html' -// @has - '//*[@id="reexport.hidden_reexport"]/code' 'pub use hidden::inside_hidden as hidden_reexport;' +// @has - '//*[@class="item-name"]/span[@title="Hidden item"]' '👻' + +// @has - '//*[@id="reexport.hidden_reexport"]/code' '#[doc(hidden)] pub use hidden::inside_hidden as hidden_reexport;' #[doc(hidden)] pub use hidden::inside_hidden as hidden_reexport; // @has - '//*[@class="item-name"]/a[@class="trait"]' 'TraitHidden' // @has 'foo/trait.TraitHidden.html' +// @has - '//code' '#[doc(hidden)] pub trait TraitHidden' #[doc(hidden)] pub trait TraitHidden {} // @has 'foo/index.html' '//*[@class="item-name"]/a[@class="trait"]' 'Trait' pub trait Trait { // @has 'foo/trait.Trait.html' - // @has - '//*[@id="associatedconstant.BAR"]/*[@class="code-header"]' 'const BAR: u32 = 0u32' + // @has - '//*[@id="associatedconstant.BAR"]/*[@class="code-header"]' '#[doc(hidden)] const BAR: u32 = 0u32' #[doc(hidden)] const BAR: u32 = 0; @@ -41,14 +44,15 @@ impl Struct { } impl Trait for Struct { - // @has - '//*[@id="associatedconstant.BAR"]/*[@class="code-header"]' 'const BAR: u32 = 0u32' - // @has - '//*[@id="method.foo"]/*[@class="code-header"]' 'fn foo()' + // @has - '//*[@id="associatedconstant.BAR"]/*[@class="code-header"]' '#[doc(hidden)] const BAR: u32 = 0u32' + // @has - '//*[@id="method.foo"]/*[@class="code-header"]' '#[doc(hidden)] fn foo()' } // @has - '//*[@id="impl-TraitHidden-for-Struct"]/*[@class="code-header"]' 'impl TraitHidden for Struct' impl TraitHidden for Struct {} // @has 'foo/index.html' '//*[@class="item-name"]/a[@class="enum"]' 'HiddenEnum' // @has 'foo/enum.HiddenEnum.html' +// @has - '//code' '#[doc(hidden)] pub enum HiddenEnum' #[doc(hidden)] pub enum HiddenEnum { A, diff --git a/tests/ui-fulldeps/stable-mir/check_transform.rs b/tests/ui-fulldeps/stable-mir/check_transform.rs new file mode 100644 index 00000000000..e7d852a27df --- /dev/null +++ b/tests/ui-fulldeps/stable-mir/check_transform.rs @@ -0,0 +1,147 @@ +//@ run-pass +//! Test a few methods to transform StableMIR. + +//@ ignore-stage1 +//@ ignore-cross-compile +//@ ignore-remote +//@ ignore-windows-gnu mingw has troubles with linking https://github.com/rust-lang/rust/pull/116837 + +#![feature(rustc_private)] +#![feature(assert_matches)] +#![feature(control_flow_enum)] +#![feature(ascii_char, ascii_char_variants)] + +extern crate rustc_hir; +#[macro_use] +extern crate rustc_smir; +extern crate rustc_driver; +extern crate rustc_interface; +extern crate stable_mir; + +use rustc_smir::rustc_internal; +use stable_mir::mir::alloc::GlobalAlloc; +use stable_mir::mir::mono::Instance; +use stable_mir::mir::{Body, Constant, Operand, Rvalue, StatementKind, TerminatorKind}; +use stable_mir::ty::{Const, ConstantKind}; +use stable_mir::{CrateDef, CrateItems, ItemKind}; +use std::convert::TryFrom; +use std::io::Write; +use std::ops::ControlFlow; + +const CRATE_NAME: &str = "input"; + +/// This function uses the Stable MIR APIs to transform the MIR. +fn test_transform() -> ControlFlow<()> { + // Find items in the local crate. + let items = stable_mir::all_local_items(); + + // Test fn_abi + let target_fn = *get_item(&items, (ItemKind::Fn, "dummy")).unwrap(); + let instance = Instance::try_from(target_fn).unwrap(); + let body = instance.body().unwrap(); + check_msg(&body, "oops"); + + let new_msg = "new panic message"; + let new_body = change_panic_msg(body, new_msg); + check_msg(&new_body, new_msg); + + ControlFlow::Continue(()) +} + +/// Check that the body panic message matches the given message. +fn check_msg(body: &Body, expected: &str) { + let msg = body + .blocks + .iter() + .find_map(|bb| match &bb.terminator.kind { + TerminatorKind::Call { args, .. } => { + assert_eq!(args.len(), 1, "Expected panic message, but found {args:?}"); + let msg_const = match &args[0] { + Operand::Constant(msg_const) => msg_const, + Operand::Copy(place) | Operand::Move(place) => { + assert!(place.projection.is_empty()); + bb.statements + .iter() + .find_map(|stmt| match &stmt.kind { + StatementKind::Assign( + destination, + Rvalue::Use(Operand::Constant(msg_const)), + ) if destination == place => Some(msg_const), + _ => None, + }) + .unwrap() + } + }; + let ConstantKind::Allocated(alloc) = msg_const.literal.kind() else { + unreachable!() + }; + assert_eq!(alloc.provenance.ptrs.len(), 1); + + let alloc_prov_id = alloc.provenance.ptrs[0].1 .0; + let GlobalAlloc::Memory(val) = GlobalAlloc::from(alloc_prov_id) else { + unreachable!() + }; + let bytes = val.raw_bytes().unwrap(); + Some(std::str::from_utf8(&bytes).unwrap().to_string()) + } + _ => None, + }) + .expect("Failed to find panic message"); + assert_eq!(&msg, expected); +} + +/// Modify body to use a different panic message. +fn change_panic_msg(mut body: Body, new_msg: &str) -> Body { + for bb in &mut body.blocks { + match &mut bb.terminator.kind { + TerminatorKind::Call { args, .. } => { + let new_const = Const::from_str(new_msg); + args[0] = Operand::Constant(Constant { + literal: new_const, + span: bb.terminator.span, + user_ty: None, + }); + } + _ => {} + } + } + body +} + +fn get_item<'a>( + items: &'a CrateItems, + item: (ItemKind, &str), +) -> Option<&'a stable_mir::CrateItem> { + items.iter().find(|crate_item| (item.0 == crate_item.kind()) && crate_item.name() == item.1) +} + +/// This test will generate and analyze a dummy crate using the stable mir. +/// For that, it will first write the dummy crate into a file. +/// Then it will create a `StableMir` using custom arguments and then +/// it will run the compiler. +fn main() { + let path = "transform_input.rs"; + generate_input(&path).unwrap(); + let args = vec![ + "rustc".to_string(), + "--crate-type=lib".to_string(), + "--crate-name".to_string(), + CRATE_NAME.to_string(), + path.to_string(), + ]; + run!(args, test_transform).unwrap(); +} + +fn generate_input(path: &str) -> std::io::Result<()> { + let mut file = std::fs::File::create(path)?; + write!( + file, + r#" + #![feature(panic_internals)] + pub fn dummy() {{ + core::panicking::panic_str("oops"); + }} + "# + )?; + Ok(()) +} diff --git a/tests/ui/associated-type-bounds/dedup-normalized-1.rs b/tests/ui/associated-type-bounds/dedup-normalized-1.rs new file mode 100644 index 00000000000..5329018e79f --- /dev/null +++ b/tests/ui/associated-type-bounds/dedup-normalized-1.rs @@ -0,0 +1,24 @@ +//@ check-pass + +// We try to prove `T::Rigid: Into<?0>` and have 2 candidates from where-clauses: +// +// - `Into<String>` +// - `Into<<T::Rigid as Elaborate>::Assoc>` +// +// This causes ambiguity unless we normalize the alias in the second candidate +// to detect that they actually result in the same constraints. +trait Trait { + type Rigid: Elaborate<Assoc = String> + Into<String>; +} + +trait Elaborate: Into<Self::Assoc> { + type Assoc; +} + +fn impls<T: Into<U>, U>(_: T) {} + +fn test<P: Trait>(rigid: P::Rigid) { + impls(rigid); +} + +fn main() {} diff --git a/tests/ui/associated-type-bounds/dedup-normalized-2-higher-ranked.rs b/tests/ui/associated-type-bounds/dedup-normalized-2-higher-ranked.rs new file mode 100644 index 00000000000..9224d47d30f --- /dev/null +++ b/tests/ui/associated-type-bounds/dedup-normalized-2-higher-ranked.rs @@ -0,0 +1,27 @@ +// We try to prove `for<'b> T::Rigid: Bound<'b, ?0>` and have 2 candidates from where-clauses: +// +// - `for<'a> Bound<'a, String>` +// - `for<'a> Bound<'a, <T::Rigid as Elaborate>::Assoc>` +// +// This causes ambiguity unless we normalize the alias in the second candidate +// to detect that they actually result in the same constraints. We currently +// fail to detect that the constraints from these bounds are equal and error +// with ambiguity. +trait Bound<'a, U> {} + +trait Trait { + type Rigid: Elaborate<Assoc = String> + for<'a> Bound<'a, String>; +} + +trait Elaborate: for<'a> Bound<'a, Self::Assoc> { + type Assoc; +} + +fn impls<T: for<'b> Bound<'b, U>, U>(_: T) {} + +fn test<P: Trait>(rigid: P::Rigid) { + impls(rigid); + //~^ ERROR type annotations needed +} + +fn main() {} diff --git a/tests/ui/associated-type-bounds/dedup-normalized-2-higher-ranked.stderr b/tests/ui/associated-type-bounds/dedup-normalized-2-higher-ranked.stderr new file mode 100644 index 00000000000..372d379de5a --- /dev/null +++ b/tests/ui/associated-type-bounds/dedup-normalized-2-higher-ranked.stderr @@ -0,0 +1,20 @@ +error[E0283]: type annotations needed + --> $DIR/dedup-normalized-2-higher-ranked.rs:23:5 + | +LL | impls(rigid); + | ^^^^^ cannot infer type of the type parameter `U` declared on the function `impls` + | + = note: cannot satisfy `for<'b> <P as Trait>::Rigid: Bound<'b, _>` +note: required by a bound in `impls` + --> $DIR/dedup-normalized-2-higher-ranked.rs:20:13 + | +LL | fn impls<T: for<'b> Bound<'b, U>, U>(_: T) {} + | ^^^^^^^^^^^^^^^^^^^^ required by this bound in `impls` +help: consider specifying the generic arguments + | +LL | impls::<<P as Trait>::Rigid, U>(rigid); + | ++++++++++++++++++++++++++ + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0283`. diff --git a/tests/ui/async-await/in-trait/hir-hash.rs b/tests/ui/async-await/in-trait/hir-hash.rs new file mode 100644 index 00000000000..8324fec8282 --- /dev/null +++ b/tests/ui/async-await/in-trait/hir-hash.rs @@ -0,0 +1,11 @@ +// Issue #122508 + +//@ check-pass +//@ incremental +//@ edition:2021 + +trait MyTrait { + async fn bar(&self) -> i32; +} + +fn main() {} diff --git a/tests/ui/async-await/return-type-notation/issue-110963-early.stderr b/tests/ui/async-await/return-type-notation/issue-110963-early.stderr index feae2698e8f..23ede089b5a 100644 --- a/tests/ui/async-await/return-type-notation/issue-110963-early.stderr +++ b/tests/ui/async-await/return-type-notation/issue-110963-early.stderr @@ -7,7 +7,7 @@ LL | #![feature(return_type_notation)] = note: see issue #109417 <https://github.com/rust-lang/rust/issues/109417> for more information = note: `#[warn(incomplete_features)]` on by default -error[E0308]: mismatched types +error: implementation of `Send` is not general enough --> $DIR/issue-110963-early.rs:14:5 | LL | / spawn(async move { @@ -16,17 +16,12 @@ LL | | if !hc.check().await { LL | | log_health_check_failure().await; LL | | } LL | | }); - | |______^ one type is more general than the other + | |______^ implementation of `Send` is not general enough | - = note: expected trait `Send` - found trait `for<'a> Send` -note: the lifetime requirement is introduced here - --> $DIR/issue-110963-early.rs:34:17 - | -LL | F: Future + Send + 'static, - | ^^^^ + = note: `Send` would have to be implemented for the type `impl Future<Output = bool> { <HC as HealthCheck>::check<'0>() }`, for any two lifetimes `'0` and `'1`... + = note: ...but `Send` is actually implemented for the type `impl Future<Output = bool> { <HC as HealthCheck>::check<'2>() }`, for some specific lifetime `'2` -error[E0308]: mismatched types +error: implementation of `Send` is not general enough --> $DIR/issue-110963-early.rs:14:5 | LL | / spawn(async move { @@ -35,17 +30,11 @@ LL | | if !hc.check().await { LL | | log_health_check_failure().await; LL | | } LL | | }); - | |______^ one type is more general than the other - | - = note: expected trait `Send` - found trait `for<'a> Send` -note: the lifetime requirement is introduced here - --> $DIR/issue-110963-early.rs:34:17 + | |______^ implementation of `Send` is not general enough | -LL | F: Future + Send + 'static, - | ^^^^ + = note: `Send` would have to be implemented for the type `impl Future<Output = bool> { <HC as HealthCheck>::check<'0>() }`, for any two lifetimes `'0` and `'1`... + = note: ...but `Send` is actually implemented for the type `impl Future<Output = bool> { <HC as HealthCheck>::check<'2>() }`, for some specific lifetime `'2` = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error: aborting due to 2 previous errors; 1 warning emitted -For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/borrowck/clone-on-ref.fixed b/tests/ui/borrowck/clone-on-ref.fixed new file mode 100644 index 00000000000..b6927ba590e --- /dev/null +++ b/tests/ui/borrowck/clone-on-ref.fixed @@ -0,0 +1,32 @@ +//@ run-rustfix +fn foo<T: Default + Clone>(list: &mut Vec<T>) { + let mut cloned_items = Vec::new(); + for v in list.iter() { + cloned_items.push(v.clone()) + } + list.push(T::default()); + //~^ ERROR cannot borrow `*list` as mutable because it is also borrowed as immutable + drop(cloned_items); +} +fn bar<T: std::fmt::Display + Clone>(x: T) { + let a = &x; + let b = a.clone(); + drop(x); + //~^ ERROR cannot move out of `x` because it is borrowed + println!("{b}"); +} +#[derive(Debug)] +#[derive(Clone)] +struct A; +fn qux(x: A) { + let a = &x; + let b = a.clone(); + drop(x); + //~^ ERROR cannot move out of `x` because it is borrowed + println!("{b:?}"); +} +fn main() { + foo(&mut vec![1, 2, 3]); + bar(""); + qux(A); +} diff --git a/tests/ui/borrowck/clone-on-ref.rs b/tests/ui/borrowck/clone-on-ref.rs new file mode 100644 index 00000000000..f8c94d3cce3 --- /dev/null +++ b/tests/ui/borrowck/clone-on-ref.rs @@ -0,0 +1,31 @@ +//@ run-rustfix +fn foo<T: Default>(list: &mut Vec<T>) { + let mut cloned_items = Vec::new(); + for v in list.iter() { + cloned_items.push(v.clone()) + } + list.push(T::default()); + //~^ ERROR cannot borrow `*list` as mutable because it is also borrowed as immutable + drop(cloned_items); +} +fn bar<T: std::fmt::Display>(x: T) { + let a = &x; + let b = a.clone(); + drop(x); + //~^ ERROR cannot move out of `x` because it is borrowed + println!("{b}"); +} +#[derive(Debug)] +struct A; +fn qux(x: A) { + let a = &x; + let b = a.clone(); + drop(x); + //~^ ERROR cannot move out of `x` because it is borrowed + println!("{b:?}"); +} +fn main() { + foo(&mut vec![1, 2, 3]); + bar(""); + qux(A); +} diff --git a/tests/ui/borrowck/clone-on-ref.stderr b/tests/ui/borrowck/clone-on-ref.stderr new file mode 100644 index 00000000000..ee4fcadf55a --- /dev/null +++ b/tests/ui/borrowck/clone-on-ref.stderr @@ -0,0 +1,64 @@ +error[E0502]: cannot borrow `*list` as mutable because it is also borrowed as immutable + --> $DIR/clone-on-ref.rs:7:5 + | +LL | for v in list.iter() { + | ---- immutable borrow occurs here +LL | cloned_items.push(v.clone()) + | ------- this call doesn't do anything, the result is still `&T` because `T` doesn't implement `Clone` +LL | } +LL | list.push(T::default()); + | ^^^^^^^^^^^^^^^^^^^^^^^ mutable borrow occurs here +LL | +LL | drop(cloned_items); + | ------------ immutable borrow later used here + | +help: consider further restricting this bound + | +LL | fn foo<T: Default + Clone>(list: &mut Vec<T>) { + | +++++++ + +error[E0505]: cannot move out of `x` because it is borrowed + --> $DIR/clone-on-ref.rs:14:10 + | +LL | fn bar<T: std::fmt::Display>(x: T) { + | - binding `x` declared here +LL | let a = &x; + | -- borrow of `x` occurs here +LL | let b = a.clone(); + | ------- this call doesn't do anything, the result is still `&T` because `T` doesn't implement `Clone` +LL | drop(x); + | ^ move out of `x` occurs here +LL | +LL | println!("{b}"); + | --- borrow later used here + | +help: consider further restricting this bound + | +LL | fn bar<T: std::fmt::Display + Clone>(x: T) { + | +++++++ + +error[E0505]: cannot move out of `x` because it is borrowed + --> $DIR/clone-on-ref.rs:23:10 + | +LL | fn qux(x: A) { + | - binding `x` declared here +LL | let a = &x; + | -- borrow of `x` occurs here +LL | let b = a.clone(); + | ------- this call doesn't do anything, the result is still `&A` because `A` doesn't implement `Clone` +LL | drop(x); + | ^ move out of `x` occurs here +LL | +LL | println!("{b:?}"); + | ----- borrow later used here + | +help: consider annotating `A` with `#[derive(Clone)]` + | +LL + #[derive(Clone)] +LL | struct A; + | + +error: aborting due to 3 previous errors + +Some errors have detailed explanations: E0502, E0505. +For more information about an error, try `rustc --explain E0502`. diff --git a/tests/ui/closures/multiple-fn-bounds.stderr b/tests/ui/closures/multiple-fn-bounds.stderr index 9a49fc99ac3..861b39b4d07 100644 --- a/tests/ui/closures/multiple-fn-bounds.stderr +++ b/tests/ui/closures/multiple-fn-bounds.stderr @@ -8,7 +8,7 @@ LL | foo(move |x| v); | expected due to this | = note: expected closure signature `fn(_) -> _` - found closure signature `for<'a> fn(&'a _) -> _` + found closure signature `fn(&_) -> _` note: closure inferred to have a different signature due to this bound --> $DIR/multiple-fn-bounds.rs:1:11 | diff --git a/tests/ui/consts/assoc_const_generic_impl.stderr b/tests/ui/consts/assoc_const_generic_impl.stderr index d826972ce9f..45219508396 100644 --- a/tests/ui/consts/assoc_const_generic_impl.stderr +++ b/tests/ui/consts/assoc_const_generic_impl.stderr @@ -4,6 +4,12 @@ error[E0080]: evaluation of `<u32 as ZeroSized>::I_AM_ZERO_SIZED` failed LL | const I_AM_ZERO_SIZED: () = [()][std::mem::size_of::<Self>()]; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ index out of bounds: the length is 1 but the index is 4 +note: erroneous constant encountered + --> $DIR/assoc_const_generic_impl.rs:11:9 + | +LL | Self::I_AM_ZERO_SIZED; + | ^^^^^^^^^^^^^^^^^^^^^ + note: the above error was encountered while instantiating `fn <u32 as ZeroSized>::requires_zero_size` --> $DIR/assoc_const_generic_impl.rs:18:5 | diff --git a/tests/ui/consts/const-eval/erroneous-const.stderr b/tests/ui/consts/const-eval/erroneous-const.stderr deleted file mode 100644 index bd25e96c2cf..00000000000 --- a/tests/ui/consts/const-eval/erroneous-const.stderr +++ /dev/null @@ -1,15 +0,0 @@ -error[E0080]: evaluation of `PrintName::<i32>::VOID` failed - --> $DIR/erroneous-const.rs:6:22 - | -LL | const VOID: () = [()][2]; - | ^^^^^^^ index out of bounds: the length is 1 but the index is 2 - -note: erroneous constant encountered - --> $DIR/erroneous-const.rs:13:13 - | -LL | PrintName::<T>::VOID; - | ^^^^^^^^^^^^^^^^^^^^ - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0080`. diff --git a/tests/ui/consts/const-eval/erroneous-const2.rs b/tests/ui/consts/const-eval/erroneous-const2.rs deleted file mode 100644 index 61f2955f2d8..00000000000 --- a/tests/ui/consts/const-eval/erroneous-const2.rs +++ /dev/null @@ -1,19 +0,0 @@ -//! Make sure we error on erroneous consts even if they are unused. -#![allow(unconditional_panic)] - -struct PrintName<T>(T); -impl<T> PrintName<T> { - const VOID: () = [()][2]; //~ERROR evaluation of `PrintName::<i32>::VOID` failed -} - -pub static FOO: () = { - if false { - // This bad constant is only used in dead code in a static initializer... and yet we still - // must make sure that the build fails. - PrintName::<i32>::VOID; //~ constant - } -}; - -fn main() { - FOO -} diff --git a/tests/ui/consts/const-eval/erroneous-const2.stderr b/tests/ui/consts/const-eval/erroneous-const2.stderr deleted file mode 100644 index 6a5839e3dfb..00000000000 --- a/tests/ui/consts/const-eval/erroneous-const2.stderr +++ /dev/null @@ -1,15 +0,0 @@ -error[E0080]: evaluation of `PrintName::<i32>::VOID` failed - --> $DIR/erroneous-const2.rs:6:22 - | -LL | const VOID: () = [()][2]; - | ^^^^^^^ index out of bounds: the length is 1 but the index is 2 - -note: erroneous constant encountered - --> $DIR/erroneous-const2.rs:13:9 - | -LL | PrintName::<i32>::VOID; - | ^^^^^^^^^^^^^^^^^^^^^^ - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0080`. diff --git a/tests/ui/consts/const-eval/index-out-of-bounds-never-type.stderr b/tests/ui/consts/const-eval/index-out-of-bounds-never-type.stderr index 4e7ef52f674..7facb2d1a5c 100644 --- a/tests/ui/consts/const-eval/index-out-of-bounds-never-type.stderr +++ b/tests/ui/consts/const-eval/index-out-of-bounds-never-type.stderr @@ -4,6 +4,12 @@ error[E0080]: evaluation of `PrintName::<()>::VOID` failed LL | const VOID: ! = { let x = 0 * std::mem::size_of::<T>(); [][x] }; | ^^^^^ index out of bounds: the length is 0 but the index is 0 +note: erroneous constant encountered + --> $DIR/index-out-of-bounds-never-type.rs:16:13 + | +LL | let _ = PrintName::<T>::VOID; + | ^^^^^^^^^^^^^^^^^^^^ + note: the above error was encountered while instantiating `fn f::<()>` --> $DIR/index-out-of-bounds-never-type.rs:20:5 | diff --git a/tests/ui/consts/const-eval/issue-50814-2.mir-opt.stderr b/tests/ui/consts/const-eval/issue-50814-2.mir-opt.stderr index 7e764ca7239..2de68d3fee9 100644 --- a/tests/ui/consts/const-eval/issue-50814-2.mir-opt.stderr +++ b/tests/ui/consts/const-eval/issue-50814-2.mir-opt.stderr @@ -10,6 +10,52 @@ note: erroneous constant encountered LL | &<A<T> as Foo<T>>::BAR | ^^^^^^^^^^^^^^^^^^^^^ +note: erroneous constant encountered + --> $DIR/issue-50814-2.rs:20:5 + | +LL | &<A<T> as Foo<T>>::BAR + | ^^^^^^^^^^^^^^^^^^^^^^ + +note: erroneous constant encountered + --> $DIR/issue-50814-2.rs:20:5 + | +LL | &<A<T> as Foo<T>>::BAR + | ^^^^^^^^^^^^^^^^^^^^^^ + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +note: erroneous constant encountered + --> $DIR/issue-50814-2.rs:20:5 + | +LL | &<A<T> as Foo<T>>::BAR + | ^^^^^^^^^^^^^^^^^^^^^^ + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +note: erroneous constant encountered + --> $DIR/issue-50814-2.rs:20:5 + | +LL | &<A<T> as Foo<T>>::BAR + | ^^^^^^^^^^^^^^^^^^^^^^ + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +note: erroneous constant encountered + --> $DIR/issue-50814-2.rs:20:6 + | +LL | &<A<T> as Foo<T>>::BAR + | ^^^^^^^^^^^^^^^^^^^^^ + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +note: erroneous constant encountered + --> $DIR/issue-50814-2.rs:20:6 + | +LL | &<A<T> as Foo<T>>::BAR + | ^^^^^^^^^^^^^^^^^^^^^ + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + error: aborting due to 1 previous error For more information about this error, try `rustc --explain E0080`. diff --git a/tests/ui/consts/const-eval/issue-50814-2.normal.stderr b/tests/ui/consts/const-eval/issue-50814-2.normal.stderr index f552c8fde5b..4a7dfb19304 100644 --- a/tests/ui/consts/const-eval/issue-50814-2.normal.stderr +++ b/tests/ui/consts/const-eval/issue-50814-2.normal.stderr @@ -10,6 +10,20 @@ note: erroneous constant encountered LL | &<A<T> as Foo<T>>::BAR | ^^^^^^^^^^^^^^^^^^^^^ +note: erroneous constant encountered + --> $DIR/issue-50814-2.rs:20:5 + | +LL | &<A<T> as Foo<T>>::BAR + | ^^^^^^^^^^^^^^^^^^^^^^ + +note: erroneous constant encountered + --> $DIR/issue-50814-2.rs:20:6 + | +LL | &<A<T> as Foo<T>>::BAR + | ^^^^^^^^^^^^^^^^^^^^^ + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + note: the above error was encountered while instantiating `fn foo::<()>` --> $DIR/issue-50814-2.rs:32:22 | diff --git a/tests/ui/consts/const-eval/issue-50814.stderr b/tests/ui/consts/const-eval/issue-50814.stderr index 8d018161401..fe0e25b820f 100644 --- a/tests/ui/consts/const-eval/issue-50814.stderr +++ b/tests/ui/consts/const-eval/issue-50814.stderr @@ -26,6 +26,20 @@ LL | &Sum::<U8, U8>::MAX | = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` +note: erroneous constant encountered + --> $DIR/issue-50814.rs:21:5 + | +LL | &Sum::<U8, U8>::MAX + | ^^^^^^^^^^^^^^^^^^^ + +note: erroneous constant encountered + --> $DIR/issue-50814.rs:21:6 + | +LL | &Sum::<U8, U8>::MAX + | ^^^^^^^^^^^^^^^^^^ + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + note: the above error was encountered while instantiating `fn foo::<i32>` --> $DIR/issue-50814.rs:26:5 | diff --git a/tests/ui/consts/const-eval/issue-85155.stderr b/tests/ui/consts/const-eval/issue-85155.stderr index a88e959a8a6..99836a3fac6 100644 --- a/tests/ui/consts/const-eval/issue-85155.stderr +++ b/tests/ui/consts/const-eval/issue-85155.stderr @@ -4,6 +4,14 @@ error[E0080]: evaluation of `post_monomorphization_error::ValidateConstImm::<2, LL | let _ = 1 / ((IMM >= MIN && IMM <= MAX) as usize); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ attempt to divide `1_usize` by zero +note: erroneous constant encountered + --> $DIR/auxiliary/post_monomorphization_error.rs:19:5 + | +LL | static_assert_imm1!(IMM1); + | ^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: this note originates in the macro `static_assert_imm1` (in Nightly builds, run with -Z macro-backtrace for more info) + note: the above error was encountered while instantiating `fn post_monomorphization_error::stdarch_intrinsic::<2>` --> $DIR/issue-85155.rs:19:5 | diff --git a/tests/ui/consts/const-eval/unused-broken-const-late.stderr b/tests/ui/consts/const-eval/unused-broken-const-late.stderr deleted file mode 100644 index c2cf2f3813c..00000000000 --- a/tests/ui/consts/const-eval/unused-broken-const-late.stderr +++ /dev/null @@ -1,11 +0,0 @@ -error[E0080]: evaluation of `PrintName::<i32>::VOID` failed - --> $DIR/unused-broken-const-late.rs:8:22 - | -LL | const VOID: () = panic!(); - | ^^^^^^^^ the evaluated program panicked at 'explicit panic', $DIR/unused-broken-const-late.rs:8:22 - | - = 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) - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0080`. diff --git a/tests/ui/consts/required-consts/collect-in-called-fn.noopt.stderr b/tests/ui/consts/required-consts/collect-in-called-fn.noopt.stderr new file mode 100644 index 00000000000..14a4cb0217f --- /dev/null +++ b/tests/ui/consts/required-consts/collect-in-called-fn.noopt.stderr @@ -0,0 +1,23 @@ +error[E0080]: evaluation of `Fail::<i32>::C` failed + --> $DIR/collect-in-called-fn.rs:9:19 + | +LL | const C: () = panic!(); + | ^^^^^^^^ the evaluated program panicked at 'explicit panic', $DIR/collect-in-called-fn.rs:9:19 + | + = 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 encountered + --> $DIR/collect-in-called-fn.rs:18:17 + | +LL | let _ = Fail::<T>::C; + | ^^^^^^^^^^^^ + +note: the above error was encountered while instantiating `fn called::<i32>` + --> $DIR/collect-in-called-fn.rs:23:5 + | +LL | called::<i32>(); + | ^^^^^^^^^^^^^^^ + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0080`. diff --git a/tests/ui/consts/required-consts/collect-in-called-fn.opt.stderr b/tests/ui/consts/required-consts/collect-in-called-fn.opt.stderr new file mode 100644 index 00000000000..14a4cb0217f --- /dev/null +++ b/tests/ui/consts/required-consts/collect-in-called-fn.opt.stderr @@ -0,0 +1,23 @@ +error[E0080]: evaluation of `Fail::<i32>::C` failed + --> $DIR/collect-in-called-fn.rs:9:19 + | +LL | const C: () = panic!(); + | ^^^^^^^^ the evaluated program panicked at 'explicit panic', $DIR/collect-in-called-fn.rs:9:19 + | + = 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 encountered + --> $DIR/collect-in-called-fn.rs:18:17 + | +LL | let _ = Fail::<T>::C; + | ^^^^^^^^^^^^ + +note: the above error was encountered while instantiating `fn called::<i32>` + --> $DIR/collect-in-called-fn.rs:23:5 + | +LL | called::<i32>(); + | ^^^^^^^^^^^^^^^ + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0080`. diff --git a/tests/ui/consts/const-eval/unused-broken-const-late.rs b/tests/ui/consts/required-consts/collect-in-called-fn.rs index c4916061f9e..55133a10cd9 100644 --- a/tests/ui/consts/const-eval/unused-broken-const-late.rs +++ b/tests/ui/consts/required-consts/collect-in-called-fn.rs @@ -1,20 +1,24 @@ +//@revisions: noopt opt //@ build-fail -//@ compile-flags: -O +//@[opt] compile-flags: -O //! Make sure we detect erroneous constants post-monomorphization even when they are unused. This is //! crucial, people rely on it for soundness. (https://github.com/rust-lang/rust/issues/112090) -struct PrintName<T>(T); -impl<T> PrintName<T> { - const VOID: () = panic!(); //~ERROR evaluation of `PrintName::<i32>::VOID` failed +struct Fail<T>(T); +impl<T> Fail<T> { + const C: () = panic!(); //~ERROR evaluation of `Fail::<i32>::C` failed } -fn no_codegen<T>() { +#[inline(never)] +fn called<T>() { // Any function that is called is guaranteed to have all consts that syntactically // appear in its body evaluated, even if they only appear in dead code. + // This relies on mono-item collection checking `required_consts` in collected functions. if false { - let _ = PrintName::<T>::VOID; + let _ = Fail::<T>::C; } } + pub fn main() { - no_codegen::<i32>(); + called::<i32>(); } diff --git a/tests/ui/consts/required-consts/collect-in-dead-drop.noopt.stderr b/tests/ui/consts/required-consts/collect-in-dead-drop.noopt.stderr new file mode 100644 index 00000000000..0bf231d09f1 --- /dev/null +++ b/tests/ui/consts/required-consts/collect-in-dead-drop.noopt.stderr @@ -0,0 +1,20 @@ +error[E0080]: evaluation of `Fail::<i32>::C` failed + --> $DIR/collect-in-dead-drop.rs:12:19 + | +LL | const C: () = panic!(); + | ^^^^^^^^ the evaluated program panicked at 'explicit panic', $DIR/collect-in-dead-drop.rs:12:19 + | + = 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 encountered + --> $DIR/collect-in-dead-drop.rs:19:17 + | +LL | let _ = Fail::<T>::C; + | ^^^^^^^^^^^^ + +note: the above error was encountered while instantiating `fn <Fail<i32> as std::ops::Drop>::drop` + --> $SRC_DIR/core/src/ptr/mod.rs:LL:COL + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0080`. diff --git a/tests/ui/consts/required-consts/collect-in-dead-drop.rs b/tests/ui/consts/required-consts/collect-in-dead-drop.rs new file mode 100644 index 00000000000..c9ffcec6903 --- /dev/null +++ b/tests/ui/consts/required-consts/collect-in-dead-drop.rs @@ -0,0 +1,33 @@ +//@revisions: noopt opt +//@[noopt] build-fail +//@[opt] compile-flags: -O +//FIXME: `opt` revision currently does not stop with an error due to +//<https://github.com/rust-lang/rust/issues/107503>. +//@[opt] build-pass +//! Make sure we detect erroneous constants post-monomorphization even when they are unused. This is +//! crucial, people rely on it for soundness. (https://github.com/rust-lang/rust/issues/112090) + +struct Fail<T>(T); +impl<T> Fail<T> { + const C: () = panic!(); //[noopt]~ERROR evaluation of `Fail::<i32>::C` failed +} + +// This function is not actually called, but is mentioned implicitly as destructor in dead code in a +// function that is called. Make sure we still find this error. +impl<T> Drop for Fail<T> { + fn drop(&mut self) { + let _ = Fail::<T>::C; + } +} + +#[inline(never)] +fn called<T>(x: T) { + if false { + let v = Fail(x); + // Now it gest dropped implicitly, at the end of this scope. + } +} + +pub fn main() { + called::<i32>(0); +} diff --git a/tests/ui/consts/required-consts/collect-in-dead-fn.noopt.stderr b/tests/ui/consts/required-consts/collect-in-dead-fn.noopt.stderr new file mode 100644 index 00000000000..8bb99efe8e4 --- /dev/null +++ b/tests/ui/consts/required-consts/collect-in-dead-fn.noopt.stderr @@ -0,0 +1,23 @@ +error[E0080]: evaluation of `Fail::<i32>::C` failed + --> $DIR/collect-in-dead-fn.rs:12:19 + | +LL | const C: () = panic!(); + | ^^^^^^^^ the evaluated program panicked at 'explicit panic', $DIR/collect-in-dead-fn.rs:12:19 + | + = 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 encountered + --> $DIR/collect-in-dead-fn.rs:22:17 + | +LL | let _ = Fail::<T>::C; + | ^^^^^^^^^^^^ + +note: the above error was encountered while instantiating `fn not_called::<i32>` + --> $DIR/collect-in-dead-fn.rs:29:9 + | +LL | not_called::<T>(); + | ^^^^^^^^^^^^^^^^^ + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0080`. diff --git a/tests/ui/consts/required-consts/collect-in-dead-fn.rs b/tests/ui/consts/required-consts/collect-in-dead-fn.rs new file mode 100644 index 00000000000..9e6b1519153 --- /dev/null +++ b/tests/ui/consts/required-consts/collect-in-dead-fn.rs @@ -0,0 +1,35 @@ +//@revisions: noopt opt +//@[noopt] build-fail +//@[opt] compile-flags: -O +//FIXME: `opt` revision currently does not stop with an error due to +//<https://github.com/rust-lang/rust/issues/107503>. +//@[opt] build-pass +//! Make sure we detect erroneous constants post-monomorphization even when they are unused. This is +//! crucial, people rely on it for soundness. (https://github.com/rust-lang/rust/issues/112090) + +struct Fail<T>(T); +impl<T> Fail<T> { + const C: () = panic!(); //[noopt]~ERROR evaluation of `Fail::<i32>::C` failed +} + +// This function is not actually called, but it is mentioned in dead code in a function that is +// called. Make sure we still find this error. +// This relies on mono-item collection checking `required_consts` in functions that syntactically +// are called in collected functions (even inside dead code). +#[inline(never)] +fn not_called<T>() { + if false { + let _ = Fail::<T>::C; + } +} + +#[inline(never)] +fn called<T>() { + if false { + not_called::<T>(); + } +} + +pub fn main() { + called::<i32>(); +} diff --git a/tests/ui/consts/required-consts/collect-in-dead-forget.rs b/tests/ui/consts/required-consts/collect-in-dead-forget.rs new file mode 100644 index 00000000000..720b7a499f7 --- /dev/null +++ b/tests/ui/consts/required-consts/collect-in-dead-forget.rs @@ -0,0 +1,32 @@ +//@revisions: noopt opt +//@build-pass +//@[opt] compile-flags: -O +//! Make sure we detect erroneous constants post-monomorphization even when they are unused. This is +//! crucial, people rely on it for soundness. (https://github.com/rust-lang/rust/issues/112090) + +struct Fail<T>(T); +impl<T> Fail<T> { + const C: () = panic!(); +} + +// This function is not actually called, but is mentioned implicitly as destructor in dead code in a +// function that is called. Make sure we still find this error. +impl<T> Drop for Fail<T> { + fn drop(&mut self) { + let _ = Fail::<T>::C; + } +} + +#[inline(never)] +fn called<T>(x: T) { + if false { + let v = Fail(x); + std::mem::forget(v); + // Now the destructor never gets "mentioned" so this build should *not* fail. + // IOW, this demonstrates that we are using a post-drop-elab notion of "mentioned". + } +} + +pub fn main() { + called::<i32>(0); +} diff --git a/tests/ui/consts/required-consts/collect-in-dead-move.noopt.stderr b/tests/ui/consts/required-consts/collect-in-dead-move.noopt.stderr new file mode 100644 index 00000000000..5b1df78b232 --- /dev/null +++ b/tests/ui/consts/required-consts/collect-in-dead-move.noopt.stderr @@ -0,0 +1,20 @@ +error[E0080]: evaluation of `Fail::<i32>::C` failed + --> $DIR/collect-in-dead-move.rs:12:19 + | +LL | const C: () = panic!(); + | ^^^^^^^^ the evaluated program panicked at 'explicit panic', $DIR/collect-in-dead-move.rs:12:19 + | + = 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 encountered + --> $DIR/collect-in-dead-move.rs:19:17 + | +LL | let _ = Fail::<T>::C; + | ^^^^^^^^^^^^ + +note: the above error was encountered while instantiating `fn <Fail<i32> as std::ops::Drop>::drop` + --> $SRC_DIR/core/src/ptr/mod.rs:LL:COL + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0080`. diff --git a/tests/ui/consts/required-consts/collect-in-dead-move.rs b/tests/ui/consts/required-consts/collect-in-dead-move.rs new file mode 100644 index 00000000000..f3a6ba8a657 --- /dev/null +++ b/tests/ui/consts/required-consts/collect-in-dead-move.rs @@ -0,0 +1,33 @@ +//@revisions: noopt opt +//@[noopt] build-fail +//@[opt] compile-flags: -O +//FIXME: `opt` revision currently does not stop with an error due to +//<https://github.com/rust-lang/rust/issues/107503>. +//@[opt] build-pass +//! Make sure we detect erroneous constants post-monomorphization even when they are unused. This is +//! crucial, people rely on it for soundness. (https://github.com/rust-lang/rust/issues/112090) + +struct Fail<T>(T); +impl<T> Fail<T> { + const C: () = panic!(); //[noopt]~ERROR evaluation of `Fail::<i32>::C` failed +} + +// This function is not actually called, but is mentioned implicitly as destructor in dead code in a +// function that is called. Make sure we still find this error. +impl<T> Drop for Fail<T> { + fn drop(&mut self) { + let _ = Fail::<T>::C; + } +} + +#[inline(never)] +fn called<T>(x: T) { + if false { + let v = Fail(x); + drop(v); // move `v` away (and it then gets dropped there so build still fails) + } +} + +pub fn main() { + called::<i32>(0); +} diff --git a/tests/ui/consts/required-consts/collect-in-dead-vtable.noopt.stderr b/tests/ui/consts/required-consts/collect-in-dead-vtable.noopt.stderr new file mode 100644 index 00000000000..56b6989b441 --- /dev/null +++ b/tests/ui/consts/required-consts/collect-in-dead-vtable.noopt.stderr @@ -0,0 +1,23 @@ +error[E0080]: evaluation of `Fail::<i32>::C` failed + --> $DIR/collect-in-dead-vtable.rs:12:19 + | +LL | const C: () = panic!(); + | ^^^^^^^^ the evaluated program panicked at 'explicit panic', $DIR/collect-in-dead-vtable.rs:12:19 + | + = 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 encountered + --> $DIR/collect-in-dead-vtable.rs:26:21 + | +LL | let _ = Fail::<T>::C; + | ^^^^^^^^^^^^ + +note: the above error was encountered while instantiating `fn <std::vec::Vec<i32> as MyTrait>::not_called` + --> $DIR/collect-in-dead-vtable.rs:35:40 + | +LL | let gen_vtable: &dyn MyTrait = &v; // vtable "appears" here + | ^^ + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0080`. diff --git a/tests/ui/consts/required-consts/collect-in-dead-vtable.rs b/tests/ui/consts/required-consts/collect-in-dead-vtable.rs new file mode 100644 index 00000000000..f21a1cc1fc2 --- /dev/null +++ b/tests/ui/consts/required-consts/collect-in-dead-vtable.rs @@ -0,0 +1,41 @@ +//@revisions: noopt opt +//@[noopt] build-fail +//@[opt] compile-flags: -O +//FIXME: `opt` revision currently does not stop with an error due to +//<https://github.com/rust-lang/rust/issues/107503>. +//@[opt] build-pass +//! Make sure we detect erroneous constants post-monomorphization even when they are unused. This is +//! crucial, people rely on it for soundness. (https://github.com/rust-lang/rust/issues/112090) + +struct Fail<T>(T); +impl<T> Fail<T> { + const C: () = panic!(); //[noopt]~ERROR evaluation of `Fail::<i32>::C` failed +} + +trait MyTrait { + fn not_called(&self); +} + +// This function is not actually called, but it is mentioned in a vtable in a function that is +// called. Make sure we still find this error. +// This relies on mono-item collection checking `required_consts` in functions that are referenced +// in vtables that syntactically appear in collected functions (even inside dead code). +impl<T> MyTrait for Vec<T> { + fn not_called(&self) { + if false { + let _ = Fail::<T>::C; + } + } +} + +#[inline(never)] +fn called<T>() { + if false { + let v: Vec<T> = Vec::new(); + let gen_vtable: &dyn MyTrait = &v; // vtable "appears" here + } +} + +pub fn main() { + called::<i32>(); +} diff --git a/tests/ui/consts/required-consts/interpret-in-const-called-fn.noopt.stderr b/tests/ui/consts/required-consts/interpret-in-const-called-fn.noopt.stderr new file mode 100644 index 00000000000..75304591b9f --- /dev/null +++ b/tests/ui/consts/required-consts/interpret-in-const-called-fn.noopt.stderr @@ -0,0 +1,17 @@ +error[E0080]: evaluation of `Fail::<i32>::C` failed + --> $DIR/interpret-in-const-called-fn.rs:7:19 + | +LL | const C: () = panic!(); + | ^^^^^^^^ the evaluated program panicked at 'explicit panic', $DIR/interpret-in-const-called-fn.rs:7:19 + | + = 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 encountered + --> $DIR/interpret-in-const-called-fn.rs:16:9 + | +LL | Fail::<T>::C; + | ^^^^^^^^^^^^ + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0080`. diff --git a/tests/ui/consts/required-consts/interpret-in-const-called-fn.opt.stderr b/tests/ui/consts/required-consts/interpret-in-const-called-fn.opt.stderr new file mode 100644 index 00000000000..75304591b9f --- /dev/null +++ b/tests/ui/consts/required-consts/interpret-in-const-called-fn.opt.stderr @@ -0,0 +1,17 @@ +error[E0080]: evaluation of `Fail::<i32>::C` failed + --> $DIR/interpret-in-const-called-fn.rs:7:19 + | +LL | const C: () = panic!(); + | ^^^^^^^^ the evaluated program panicked at 'explicit panic', $DIR/interpret-in-const-called-fn.rs:7:19 + | + = 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 encountered + --> $DIR/interpret-in-const-called-fn.rs:16:9 + | +LL | Fail::<T>::C; + | ^^^^^^^^^^^^ + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0080`. diff --git a/tests/ui/consts/const-eval/erroneous-const.rs b/tests/ui/consts/required-consts/interpret-in-const-called-fn.rs index 74d44c5259a..c409fae0bb9 100644 --- a/tests/ui/consts/const-eval/erroneous-const.rs +++ b/tests/ui/consts/required-consts/interpret-in-const-called-fn.rs @@ -1,16 +1,19 @@ +//@revisions: noopt opt +//@[opt] compile-flags: -O //! Make sure we error on erroneous consts even if they are unused. -#![allow(unconditional_panic)] -struct PrintName<T>(T); -impl<T> PrintName<T> { - const VOID: () = [()][2]; //~ERROR evaluation of `PrintName::<i32>::VOID` failed +struct Fail<T>(T); +impl<T> Fail<T> { + const C: () = panic!(); //~ERROR evaluation of `Fail::<i32>::C` failed } +#[inline(never)] const fn no_codegen<T>() { if false { // This bad constant is only used in dead code in a no-codegen function... and yet we still // must make sure that the build fails. - PrintName::<T>::VOID; //~ constant + // This relies on const-eval evaluating all `required_consts` of `const fn`. + Fail::<T>::C; //~ constant } } diff --git a/tests/ui/consts/required-consts/interpret-in-promoted.noopt.stderr b/tests/ui/consts/required-consts/interpret-in-promoted.noopt.stderr new file mode 100644 index 00000000000..491131daf8d --- /dev/null +++ b/tests/ui/consts/required-consts/interpret-in-promoted.noopt.stderr @@ -0,0 +1,27 @@ +error[E0080]: evaluation of constant value failed + --> $SRC_DIR/core/src/hint.rs:LL:COL + | + = note: entering unreachable code + | +note: inside `unreachable_unchecked` + --> $SRC_DIR/core/src/hint.rs:LL:COL +note: inside `ub` + --> $DIR/interpret-in-promoted.rs:6:5 + | +LL | std::hint::unreachable_unchecked(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +note: inside `FOO` + --> $DIR/interpret-in-promoted.rs:12:28 + | +LL | let _x: &'static () = &ub(); + | ^^^^ + +note: erroneous constant encountered + --> $DIR/interpret-in-promoted.rs:12:27 + | +LL | let _x: &'static () = &ub(); + | ^^^^^ + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0080`. diff --git a/tests/ui/consts/required-consts/interpret-in-promoted.opt.stderr b/tests/ui/consts/required-consts/interpret-in-promoted.opt.stderr new file mode 100644 index 00000000000..491131daf8d --- /dev/null +++ b/tests/ui/consts/required-consts/interpret-in-promoted.opt.stderr @@ -0,0 +1,27 @@ +error[E0080]: evaluation of constant value failed + --> $SRC_DIR/core/src/hint.rs:LL:COL + | + = note: entering unreachable code + | +note: inside `unreachable_unchecked` + --> $SRC_DIR/core/src/hint.rs:LL:COL +note: inside `ub` + --> $DIR/interpret-in-promoted.rs:6:5 + | +LL | std::hint::unreachable_unchecked(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +note: inside `FOO` + --> $DIR/interpret-in-promoted.rs:12:28 + | +LL | let _x: &'static () = &ub(); + | ^^^^ + +note: erroneous constant encountered + --> $DIR/interpret-in-promoted.rs:12:27 + | +LL | let _x: &'static () = &ub(); + | ^^^^^ + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0080`. diff --git a/tests/ui/consts/required-consts/interpret-in-promoted.rs b/tests/ui/consts/required-consts/interpret-in-promoted.rs new file mode 100644 index 00000000000..9c2cf4e70d3 --- /dev/null +++ b/tests/ui/consts/required-consts/interpret-in-promoted.rs @@ -0,0 +1,15 @@ +//@revisions: noopt opt +//@[opt] compile-flags: -O +//! Make sure we error on erroneous consts even if they are unused. + +const unsafe fn ub() { + std::hint::unreachable_unchecked(); +} + +pub const FOO: () = unsafe { + // Make sure that this gets promoted and then fails to evaluate, and we deal with that + // correctly. + let _x: &'static () = &ub(); //~ erroneous constant +}; + +fn main() {} diff --git a/tests/ui/consts/required-consts/interpret-in-static.noopt.stderr b/tests/ui/consts/required-consts/interpret-in-static.noopt.stderr new file mode 100644 index 00000000000..159c9449fc0 --- /dev/null +++ b/tests/ui/consts/required-consts/interpret-in-static.noopt.stderr @@ -0,0 +1,17 @@ +error[E0080]: evaluation of `Fail::<i32>::C` failed + --> $DIR/interpret-in-static.rs:7:19 + | +LL | const C: () = panic!(); + | ^^^^^^^^ the evaluated program panicked at 'explicit panic', $DIR/interpret-in-static.rs:7:19 + | + = 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 encountered + --> $DIR/interpret-in-static.rs:15:9 + | +LL | Fail::<i32>::C; + | ^^^^^^^^^^^^^^ + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0080`. diff --git a/tests/ui/consts/required-consts/interpret-in-static.opt.stderr b/tests/ui/consts/required-consts/interpret-in-static.opt.stderr new file mode 100644 index 00000000000..159c9449fc0 --- /dev/null +++ b/tests/ui/consts/required-consts/interpret-in-static.opt.stderr @@ -0,0 +1,17 @@ +error[E0080]: evaluation of `Fail::<i32>::C` failed + --> $DIR/interpret-in-static.rs:7:19 + | +LL | const C: () = panic!(); + | ^^^^^^^^ the evaluated program panicked at 'explicit panic', $DIR/interpret-in-static.rs:7:19 + | + = 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 encountered + --> $DIR/interpret-in-static.rs:15:9 + | +LL | Fail::<i32>::C; + | ^^^^^^^^^^^^^^ + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0080`. diff --git a/tests/ui/consts/required-consts/interpret-in-static.rs b/tests/ui/consts/required-consts/interpret-in-static.rs new file mode 100644 index 00000000000..559e281b2b0 --- /dev/null +++ b/tests/ui/consts/required-consts/interpret-in-static.rs @@ -0,0 +1,21 @@ +//@revisions: noopt opt +//@[opt] compile-flags: -O +//! Make sure we error on erroneous consts even if they are unused. + +struct Fail<T>(T); +impl<T> Fail<T> { + const C: () = panic!(); //~ERROR evaluation of `Fail::<i32>::C` failed +} + +pub static FOO: () = { + if false { + // This bad constant is only used in dead code in a static initializer... and yet we still + // must make sure that the build fails. + // This relies on const-eval evaluating all `required_consts` of the `static` MIR body. + Fail::<i32>::C; //~ constant + } +}; + +fn main() { + FOO +} diff --git a/tests/ui/coroutine/resume-arg-late-bound.rs b/tests/ui/coroutine/resume-arg-late-bound.rs index dd6d318afbc..3c2ab41047e 100644 --- a/tests/ui/coroutine/resume-arg-late-bound.rs +++ b/tests/ui/coroutine/resume-arg-late-bound.rs @@ -13,5 +13,5 @@ fn main() { *arg = true; }; test(gen); - //~^ ERROR mismatched types + //~^ ERROR implementation of `Coroutine` is not general enough } diff --git a/tests/ui/coroutine/resume-arg-late-bound.stderr b/tests/ui/coroutine/resume-arg-late-bound.stderr index a97cc6190fd..4a4ee08c529 100644 --- a/tests/ui/coroutine/resume-arg-late-bound.stderr +++ b/tests/ui/coroutine/resume-arg-late-bound.stderr @@ -1,17 +1,11 @@ -error[E0308]: mismatched types +error: implementation of `Coroutine` is not general enough --> $DIR/resume-arg-late-bound.rs:15:5 | LL | test(gen); - | ^^^^^^^^^ one type is more general than the other + | ^^^^^^^^^ implementation of `Coroutine` is not general enough | - = note: expected trait `for<'a> Coroutine<&'a mut bool>` - found trait `Coroutine<&mut bool>` -note: the lifetime requirement is introduced here - --> $DIR/resume-arg-late-bound.rs:8:17 - | -LL | fn test(a: impl for<'a> Coroutine<&'a mut bool>) {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = note: `{coroutine@$DIR/resume-arg-late-bound.rs:11:15: 11:31}` must implement `Coroutine<&'1 mut bool>`, for any lifetime `'1`... + = note: ...but it actually implements `Coroutine<&'2 mut bool>`, for some specific lifetime `'2` error: aborting due to 1 previous error -For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/diagnostic_namespace/deny_malformed_attribute.rs b/tests/ui/diagnostic_namespace/deny_malformed_attribute.rs new file mode 100644 index 00000000000..1d946a14aff --- /dev/null +++ b/tests/ui/diagnostic_namespace/deny_malformed_attribute.rs @@ -0,0 +1,7 @@ +#![deny(unknown_or_malformed_diagnostic_attributes)] + +#[diagnostic::unknown_attribute] +//~^ERROR unknown diagnostic attribute +struct Foo; + +fn main() {} diff --git a/tests/ui/diagnostic_namespace/deny_malformed_attribute.stderr b/tests/ui/diagnostic_namespace/deny_malformed_attribute.stderr new file mode 100644 index 00000000000..a646d3613de --- /dev/null +++ b/tests/ui/diagnostic_namespace/deny_malformed_attribute.stderr @@ -0,0 +1,14 @@ +error: unknown diagnostic attribute + --> $DIR/deny_malformed_attribute.rs:3:15 + | +LL | #[diagnostic::unknown_attribute] + | ^^^^^^^^^^^^^^^^^ + | +note: the lint level is defined here + --> $DIR/deny_malformed_attribute.rs:1:9 + | +LL | #![deny(unknown_or_malformed_diagnostic_attributes)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 1 previous error + diff --git a/tests/ui/generic-associated-types/ambig-hr-projection-issue-93340.next.stderr b/tests/ui/generic-associated-types/ambig-hr-projection-issue-93340.next.stderr new file mode 100644 index 00000000000..06ffff057f9 --- /dev/null +++ b/tests/ui/generic-associated-types/ambig-hr-projection-issue-93340.next.stderr @@ -0,0 +1,48 @@ +error[E0283]: type annotations needed + --> $DIR/ambig-hr-projection-issue-93340.rs:16:5 + | +LL | cmp_eq + | ^^^^^^ cannot infer type of the type parameter `A` declared on the function `cmp_eq` + | + = note: cannot satisfy `_: Scalar` +note: required by a bound in `cmp_eq` + --> $DIR/ambig-hr-projection-issue-93340.rs:9:22 + | +LL | fn cmp_eq<'a, 'b, A: Scalar, B: Scalar, O: Scalar>(a: A::RefType<'a>, b: B::RefType<'b>) -> O { + | ^^^^^^ required by this bound in `cmp_eq` +help: consider specifying the generic arguments + | +LL | cmp_eq::<A, B, O> + | +++++++++++ + +error[E0275]: overflow evaluating the requirement `impl for<'a, 'b> Fn(<A as Scalar>::RefType<'a>, <B as Scalar>::RefType<'b>) -> O == for<'a, 'b> fn(..., ...) -> ... {cmp_eq::<..., ..., ...>}` + --> $DIR/ambig-hr-projection-issue-93340.rs:16:5 + | +LL | cmp_eq + | ^^^^^^ + +error[E0275]: overflow evaluating the requirement `impl for<'a, 'b> Fn(<A as Scalar>::RefType<'a>, <B as Scalar>::RefType<'b>) -> O == for<'a, 'b> fn(..., ...) -> ... {cmp_eq::<..., ..., ...>}` + --> $DIR/ambig-hr-projection-issue-93340.rs:16:5 + | +LL | cmp_eq + | ^^^^^^ + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +error[E0275]: overflow evaluating the requirement `for<'a, 'b> fn(<O as Scalar>::RefType<'a>, <_ as Scalar>::RefType<'b>) -> _ {cmp_eq::<O, ..., ...>} <: ...` + --> $DIR/ambig-hr-projection-issue-93340.rs:14:51 + | +LL | ) -> impl Fn(A::RefType<'_>, B::RefType<'_>) -> O { + | ___________________________________________________^ +LL | | +LL | | cmp_eq +LL | | +LL | | +LL | | +LL | | } + | |_^ + +error: aborting due to 4 previous errors + +Some errors have detailed explanations: E0275, E0283. +For more information about an error, try `rustc --explain E0275`. diff --git a/tests/ui/generic-associated-types/ambig-hr-projection-issue-93340.old.stderr b/tests/ui/generic-associated-types/ambig-hr-projection-issue-93340.old.stderr new file mode 100644 index 00000000000..df2ec4ab182 --- /dev/null +++ b/tests/ui/generic-associated-types/ambig-hr-projection-issue-93340.old.stderr @@ -0,0 +1,20 @@ +error[E0283]: type annotations needed + --> $DIR/ambig-hr-projection-issue-93340.rs:16:5 + | +LL | cmp_eq + | ^^^^^^ cannot infer type of the type parameter `A` declared on the function `cmp_eq` + | + = note: cannot satisfy `_: Scalar` +note: required by a bound in `cmp_eq` + --> $DIR/ambig-hr-projection-issue-93340.rs:9:22 + | +LL | fn cmp_eq<'a, 'b, A: Scalar, B: Scalar, O: Scalar>(a: A::RefType<'a>, b: B::RefType<'b>) -> O { + | ^^^^^^ required by this bound in `cmp_eq` +help: consider specifying the generic arguments + | +LL | cmp_eq::<A, B, O> + | +++++++++++ + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0283`. diff --git a/tests/ui/generic-associated-types/ambig-hr-projection-issue-93340.rs b/tests/ui/generic-associated-types/ambig-hr-projection-issue-93340.rs new file mode 100644 index 00000000000..4d8ea9d8d48 --- /dev/null +++ b/tests/ui/generic-associated-types/ambig-hr-projection-issue-93340.rs @@ -0,0 +1,22 @@ +//@ revisions: old next +//@[next] compile-flags: -Znext-solver +pub trait Scalar: 'static { + type RefType<'a>: ScalarRef<'a>; +} + +pub trait ScalarRef<'a>: 'a {} + +fn cmp_eq<'a, 'b, A: Scalar, B: Scalar, O: Scalar>(a: A::RefType<'a>, b: B::RefType<'b>) -> O { + todo!() +} + +fn build_expression<A: Scalar, B: Scalar, O: Scalar>( +) -> impl Fn(A::RefType<'_>, B::RefType<'_>) -> O { + //[next]~^ ERROR overflow evaluating the requirement + cmp_eq + //~^ ERROR type annotations needed + //[next]~| ERROR overflow evaluating the requirement + //[next]~| ERROR overflow evaluating the requirement +} + +fn main() {} diff --git a/tests/ui/generic-associated-types/bugs/issue-88382.stderr b/tests/ui/generic-associated-types/bugs/issue-88382.stderr index 9b061528e3b..0f5e394ab61 100644 --- a/tests/ui/generic-associated-types/bugs/issue-88382.stderr +++ b/tests/ui/generic-associated-types/bugs/issue-88382.stderr @@ -1,26 +1,21 @@ -error[E0631]: type mismatch in function arguments +error[E0283]: type annotations needed --> $DIR/issue-88382.rs:26:40 | LL | do_something(SomeImplementation(), test); - | ------------ ^^^^ expected due to this - | | - | required by a bound introduced by this call -... -LL | fn test<'a, I: Iterable>(_: &mut I::Iterator<'a>) {} - | ------------------------------------------------- found signature defined here + | ^^^^ cannot infer type of the type parameter `I` declared on the function `test` | - = note: expected function signature `for<'a> fn(&'a mut std::iter::Empty<usize>) -> _` - found function signature `for<'a, 'b> fn(&'b mut <_ as Iterable>::Iterator<'a>) -> _` -note: required by a bound in `do_something` - --> $DIR/issue-88382.rs:20:48 + = note: cannot satisfy `_: Iterable` + = help: the trait `Iterable` is implemented for `SomeImplementation` +note: required by a bound in `test` + --> $DIR/issue-88382.rs:29:16 | -LL | fn do_something<I: Iterable>(i: I, mut f: impl for<'a> Fn(&mut I::Iterator<'a>)) { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `do_something` -help: consider wrapping the function in a closure +LL | fn test<'a, I: Iterable>(_: &mut I::Iterator<'a>) {} + | ^^^^^^^^ required by this bound in `test` +help: consider specifying the generic argument | -LL | do_something(SomeImplementation(), |arg0: &mut std::iter::Empty<usize>| test(/* &mut <_ as Iterable>::Iterator<'_> */)); - | ++++++++++++++++++++++++++++++++++++ ++++++++++++++++++++++++++++++++++++++++++ +LL | do_something(SomeImplementation(), test::<I>); + | +++++ error: aborting due to 1 previous error -For more information about this error, try `rustc --explain E0631`. +For more information about this error, try `rustc --explain E0283`. diff --git a/tests/ui/generic-associated-types/issue-93340.rs b/tests/ui/generic-associated-types/rigid-hr-projection-issue-93340.rs index 783f8c06ebf..b55ca845cd3 100644 --- a/tests/ui/generic-associated-types/issue-93340.rs +++ b/tests/ui/generic-associated-types/rigid-hr-projection-issue-93340.rs @@ -1,3 +1,5 @@ +//@ revisions: old next +//@[next] compile-flags: -Znext-solver //@ check-pass pub trait Scalar: 'static { @@ -12,7 +14,7 @@ fn cmp_eq<'a, 'b, A: Scalar, B: Scalar, O: Scalar>(a: A::RefType<'a>, b: B::RefT fn build_expression<A: Scalar, B: Scalar, O: Scalar>( ) -> impl Fn(A::RefType<'_>, B::RefType<'_>) -> O { - cmp_eq + cmp_eq::<A, B, O> } fn main() {} diff --git a/tests/ui/generics/post_monomorphization_error_backtrace.rs b/tests/ui/generics/post_monomorphization_error_backtrace.rs index 56155ae2bd5..2c18f2b233a 100644 --- a/tests/ui/generics/post_monomorphization_error_backtrace.rs +++ b/tests/ui/generics/post_monomorphization_error_backtrace.rs @@ -12,6 +12,9 @@ fn assert_zst<T>() { //~| NOTE: the evaluated program panicked } F::<T>::V; + //~^NOTE: erroneous constant + //~|NOTE: erroneous constant + //~|NOTE: duplicate } fn foo<U>() { diff --git a/tests/ui/generics/post_monomorphization_error_backtrace.stderr b/tests/ui/generics/post_monomorphization_error_backtrace.stderr index 0d707d83d26..8a57979bca7 100644 --- a/tests/ui/generics/post_monomorphization_error_backtrace.stderr +++ b/tests/ui/generics/post_monomorphization_error_backtrace.stderr @@ -6,8 +6,14 @@ LL | const V: () = assert!(std::mem::size_of::<T>() == 0); | = note: this error originates in the macro `assert` (in Nightly builds, run with -Z macro-backtrace for more info) +note: erroneous constant encountered + --> $DIR/post_monomorphization_error_backtrace.rs:14:5 + | +LL | F::<T>::V; + | ^^^^^^^^^ + note: the above error was encountered while instantiating `fn assert_zst::<u32>` - --> $DIR/post_monomorphization_error_backtrace.rs:18:5 + --> $DIR/post_monomorphization_error_backtrace.rs:21:5 | LL | assert_zst::<U>() | ^^^^^^^^^^^^^^^^^ @@ -20,8 +26,16 @@ LL | const V: () = assert!(std::mem::size_of::<T>() == 0); | = note: this error originates in the macro `assert` (in Nightly builds, run with -Z macro-backtrace for more info) +note: erroneous constant encountered + --> $DIR/post_monomorphization_error_backtrace.rs:14:5 + | +LL | F::<T>::V; + | ^^^^^^^^^ + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + note: the above error was encountered while instantiating `fn assert_zst::<i32>` - --> $DIR/post_monomorphization_error_backtrace.rs:18:5 + --> $DIR/post_monomorphization_error_backtrace.rs:21:5 | LL | assert_zst::<U>() | ^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/half-open-range-patterns/half-open-range-pats-exhaustive-fail.stderr b/tests/ui/half-open-range-patterns/half-open-range-pats-exhaustive-fail.stderr index 6b20a820b73..bb4c2a4c523 100644 --- a/tests/ui/half-open-range-patterns/half-open-range-pats-exhaustive-fail.stderr +++ b/tests/ui/half-open-range-patterns/half-open-range-pats-exhaustive-fail.stderr @@ -394,17 +394,17 @@ help: ensure that all possible cases are being handled by adding a match arm wit LL | match $s { $($t)+ => {}, u128::MAX => todo!() } | ++++++++++++++++++++++ -error[E0004]: non-exhaustive patterns: `340282366920938463463374607431768211454_u128..=u128::MAX` not covered +error[E0004]: non-exhaustive patterns: `340282366920938463463374607431768211454_u128..` not covered --> $DIR/half-open-range-pats-exhaustive-fail.rs:93:12 | LL | m!(0, ..ALMOST_MAX); - | ^ pattern `340282366920938463463374607431768211454_u128..=u128::MAX` not covered + | ^ pattern `340282366920938463463374607431768211454_u128..` not covered | = note: the matched value is of type `u128` help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown | -LL | match $s { $($t)+ => {}, 340282366920938463463374607431768211454_u128..=u128::MAX => todo!() } - | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +LL | match $s { $($t)+ => {}, 340282366920938463463374607431768211454_u128.. => todo!() } + | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ error[E0004]: non-exhaustive patterns: `0_u128` not covered --> $DIR/half-open-range-pats-exhaustive-fail.rs:94:12 @@ -754,17 +754,17 @@ help: ensure that all possible cases are being handled by adding a match arm wit LL | match $s { $($t)+ => {}, i128::MAX => todo!() } | ++++++++++++++++++++++ -error[E0004]: non-exhaustive patterns: `170141183460469231731687303715884105726_i128..=i128::MAX` not covered +error[E0004]: non-exhaustive patterns: `170141183460469231731687303715884105726_i128..` not covered --> $DIR/half-open-range-pats-exhaustive-fail.rs:161:12 | LL | m!(0, ..ALMOST_MAX); - | ^ pattern `170141183460469231731687303715884105726_i128..=i128::MAX` not covered + | ^ pattern `170141183460469231731687303715884105726_i128..` not covered | = note: the matched value is of type `i128` help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown | -LL | match $s { $($t)+ => {}, 170141183460469231731687303715884105726_i128..=i128::MAX => todo!() } - | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +LL | match $s { $($t)+ => {}, 170141183460469231731687303715884105726_i128.. => todo!() } + | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ error[E0004]: non-exhaustive patterns: `i128::MIN` not covered --> $DIR/half-open-range-pats-exhaustive-fail.rs:162:12 diff --git a/tests/ui/higher-ranked/higher-ranked-lifetime-error.rs b/tests/ui/higher-ranked/higher-ranked-lifetime-error.rs index aee5db83669..f89a37c8512 100644 --- a/tests/ui/higher-ranked/higher-ranked-lifetime-error.rs +++ b/tests/ui/higher-ranked/higher-ranked-lifetime-error.rs @@ -10,5 +10,5 @@ fn id(x: &String) -> &String { fn main() { assert_all::<_, &String>(id); - //~^ mismatched types + //~^ ERROR implementation of `FnMut` is not general enough } diff --git a/tests/ui/higher-ranked/higher-ranked-lifetime-error.stderr b/tests/ui/higher-ranked/higher-ranked-lifetime-error.stderr index c25e731d962..d7add865aa0 100644 --- a/tests/ui/higher-ranked/higher-ranked-lifetime-error.stderr +++ b/tests/ui/higher-ranked/higher-ranked-lifetime-error.stderr @@ -1,12 +1,11 @@ -error[E0308]: mismatched types +error: implementation of `FnMut` is not general enough --> $DIR/higher-ranked-lifetime-error.rs:12:5 | LL | assert_all::<_, &String>(id); - | ^^^^^^^^^^^^^^^^^^^^^^^^ one type is more general than the other + | ^^^^^^^^^^^^^^^^^^^^^^^^ implementation of `FnMut` is not general enough | - = note: expected trait `for<'a> <for<'a> fn(&'a String) -> &'a String {id} as FnMut<(&'a String,)>>` - found trait `for<'a> <for<'a> fn(&'a String) -> &'a String {id} as FnMut<(&'a String,)>>` + = note: `for<'a> fn(&'a String) -> &'a String {id}` must implement `FnMut<(&String,)>` + = note: ...but it actually implements `FnMut<(&'0 String,)>`, for some specific lifetime `'0` error: aborting due to 1 previous error -For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/higher-ranked/trait-bounds/issue-59311.rs b/tests/ui/higher-ranked/trait-bounds/issue-59311.rs index 387c78a802a..4e722dc0e80 100644 --- a/tests/ui/higher-ranked/trait-bounds/issue-59311.rs +++ b/tests/ui/higher-ranked/trait-bounds/issue-59311.rs @@ -6,17 +6,17 @@ // an error, but the regression test is here to ensure // that it does not ICE. See discussion on #74889 for details. -pub trait T { +pub trait Trait { fn t<F: Fn()>(&self, _: F) {} } pub fn crash<V>(v: &V) where - for<'a> &'a V: T + 'static, + for<'a> &'a V: Trait + 'static, { v.t(|| {}); - //~^ ERROR: higher-ranked lifetime error - //~| ERROR: higher-ranked lifetime error + //~^ ERROR: implementation of `Trait` is not general enough + //~| ERROR: implementation of `Trait` is not general enough //~| ERROR: higher-ranked lifetime error } diff --git a/tests/ui/higher-ranked/trait-bounds/issue-59311.stderr b/tests/ui/higher-ranked/trait-bounds/issue-59311.stderr index 3053a299802..f8bed86ccf5 100644 --- a/tests/ui/higher-ranked/trait-bounds/issue-59311.stderr +++ b/tests/ui/higher-ranked/trait-bounds/issue-59311.stderr @@ -1,18 +1,20 @@ -error: higher-ranked lifetime error +error: implementation of `Trait` is not general enough --> $DIR/issue-59311.rs:17:5 | LL | v.t(|| {}); - | ^^^^^^^^^^ + | ^^^^^^^^^^ implementation of `Trait` is not general enough | - = note: could not prove `{closure@$DIR/issue-59311.rs:17:9: 17:11} well-formed` + = note: `Trait` would have to be implemented for the type `&'a V` + = note: ...but `Trait` is actually implemented for the type `&'0 V`, for some specific lifetime `'0` -error: higher-ranked lifetime error +error: implementation of `Trait` is not general enough --> $DIR/issue-59311.rs:17:5 | LL | v.t(|| {}); - | ^^^^^^^^^^ + | ^^^^^^^^^^ implementation of `Trait` is not general enough | - = note: could not prove `{closure@$DIR/issue-59311.rs:17:9: 17:11} well-formed` + = note: `Trait` would have to be implemented for the type `&'a V` + = note: ...but `Trait` is actually implemented for the type `&'0 V`, for some specific lifetime `'0` = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error: higher-ranked lifetime error diff --git a/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/issue-71955.rs b/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/issue-71955.rs index 4bd3b96e475..a44ed9e5ef5 100644 --- a/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/issue-71955.rs +++ b/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/issue-71955.rs @@ -43,9 +43,9 @@ fn main() { } foo(bar, "string", |s| s.len() == 5); - //~^ ERROR mismatched types - //~| ERROR mismatched types + //~^ ERROR implementation of `FnOnce` is not general enough + //~| ERROR implementation of `FnOnce` is not general enough foo(baz, "string", |s| s.0.len() == 5); - //~^ ERROR mismatched types - //~| ERROR mismatched types + //~^ ERROR implementation of `FnOnce` is not general enough + //~| ERROR implementation of `FnOnce` is not general enough } diff --git a/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/issue-71955.stderr b/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/issue-71955.stderr index 1cf364aa9f6..b2bb417a8f0 100644 --- a/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/issue-71955.stderr +++ b/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/issue-71955.stderr @@ -1,79 +1,40 @@ -error[E0308]: mismatched types +error: implementation of `FnOnce` is not general enough --> $DIR/issue-71955.rs:45:5 | LL | foo(bar, "string", |s| s.len() == 5); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ one type is more general than the other + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ implementation of `FnOnce` is not general enough | - = note: expected trait `for<'a, 'b> FnOnce(&'a &'b str)` - found trait `for<'a> FnOnce(&'a &str)` -note: this closure does not fulfill the lifetime requirements - --> $DIR/issue-71955.rs:45:24 - | -LL | foo(bar, "string", |s| s.len() == 5); - | ^^^ -note: the lifetime requirement is introduced here - --> $DIR/issue-71955.rs:25:9 - | -LL | F2: FnOnce(&<F1 as Parser>::Output) -> bool - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = note: closure with signature `for<'a> fn(&'a &'2 str) -> bool` must implement `FnOnce<(&&'1 str,)>`, for any lifetime `'1`... + = note: ...but it actually implements `FnOnce<(&&'2 str,)>`, for some specific lifetime `'2` -error[E0308]: mismatched types +error: implementation of `FnOnce` is not general enough --> $DIR/issue-71955.rs:45:5 | LL | foo(bar, "string", |s| s.len() == 5); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ one type is more general than the other - | - = note: expected trait `for<'a, 'b> FnOnce(&'a &'b str)` - found trait `for<'a> FnOnce(&'a &str)` -note: this closure does not fulfill the lifetime requirements - --> $DIR/issue-71955.rs:45:24 - | -LL | foo(bar, "string", |s| s.len() == 5); - | ^^^ -note: the lifetime requirement is introduced here - --> $DIR/issue-71955.rs:25:44 + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ implementation of `FnOnce` is not general enough | -LL | F2: FnOnce(&<F1 as Parser>::Output) -> bool - | ^^^^ + = note: closure with signature `for<'a> fn(&'a &'2 str) -> bool` must implement `FnOnce<(&&'1 str,)>`, for any lifetime `'1`... + = note: ...but it actually implements `FnOnce<(&&'2 str,)>`, for some specific lifetime `'2` + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` -error[E0308]: mismatched types +error: implementation of `FnOnce` is not general enough --> $DIR/issue-71955.rs:48:5 | LL | foo(baz, "string", |s| s.0.len() == 5); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ one type is more general than the other + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ implementation of `FnOnce` is not general enough | - = note: expected trait `for<'a, 'b> FnOnce(&'a Wrapper<'b>)` - found trait `for<'a> FnOnce(&'a Wrapper<'_>)` -note: this closure does not fulfill the lifetime requirements - --> $DIR/issue-71955.rs:48:24 - | -LL | foo(baz, "string", |s| s.0.len() == 5); - | ^^^ -note: the lifetime requirement is introduced here - --> $DIR/issue-71955.rs:25:9 - | -LL | F2: FnOnce(&<F1 as Parser>::Output) -> bool - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = note: closure with signature `for<'a> fn(&'a Wrapper<'2>) -> bool` must implement `FnOnce<(&Wrapper<'1>,)>`, for any lifetime `'1`... + = note: ...but it actually implements `FnOnce<(&Wrapper<'2>,)>`, for some specific lifetime `'2` -error[E0308]: mismatched types +error: implementation of `FnOnce` is not general enough --> $DIR/issue-71955.rs:48:5 | LL | foo(baz, "string", |s| s.0.len() == 5); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ one type is more general than the other - | - = note: expected trait `for<'a, 'b> FnOnce(&'a Wrapper<'b>)` - found trait `for<'a> FnOnce(&'a Wrapper<'_>)` -note: this closure does not fulfill the lifetime requirements - --> $DIR/issue-71955.rs:48:24 - | -LL | foo(baz, "string", |s| s.0.len() == 5); - | ^^^ -note: the lifetime requirement is introduced here - --> $DIR/issue-71955.rs:25:44 + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ implementation of `FnOnce` is not general enough | -LL | F2: FnOnce(&<F1 as Parser>::Output) -> bool - | ^^^^ + = note: closure with signature `for<'a> fn(&'a Wrapper<'2>) -> bool` must implement `FnOnce<(&Wrapper<'1>,)>`, for any lifetime `'1`... + = note: ...but it actually implements `FnOnce<(&Wrapper<'2>,)>`, for some specific lifetime `'2` + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error: aborting due to 4 previous errors -For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/impl-trait/in-trait/ensure-rpitits-are-created-before-freezing.rs b/tests/ui/impl-trait/in-trait/ensure-rpitits-are-created-before-freezing.rs new file mode 100644 index 00000000000..35a6acca52c --- /dev/null +++ b/tests/ui/impl-trait/in-trait/ensure-rpitits-are-created-before-freezing.rs @@ -0,0 +1,13 @@ +trait Iterable { + type Item; + fn iter(&self) -> impl Sized; +} + +// `ty::Error` in a trait ref will silence any missing item errors, but will also +// prevent the `associated_items` query from being called before def ids are frozen. +impl Iterable for Missing { +//~^ ERROR cannot find type `Missing` in this scope + fn iter(&self) -> Self::Item {} +} + +fn main() {} diff --git a/tests/ui/impl-trait/in-trait/ensure-rpitits-are-created-before-freezing.stderr b/tests/ui/impl-trait/in-trait/ensure-rpitits-are-created-before-freezing.stderr new file mode 100644 index 00000000000..c172787e6ef --- /dev/null +++ b/tests/ui/impl-trait/in-trait/ensure-rpitits-are-created-before-freezing.stderr @@ -0,0 +1,9 @@ +error[E0412]: cannot find type `Missing` in this scope + --> $DIR/ensure-rpitits-are-created-before-freezing.rs:8:19 + | +LL | impl Iterable for Missing { + | ^^^^^^^ not found in this scope + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0412`. diff --git a/tests/ui/impl-trait/in-trait/return-dont-satisfy-bounds.rs b/tests/ui/impl-trait/in-trait/return-dont-satisfy-bounds.rs index ff265e576b9..84bc39d9263 100644 --- a/tests/ui/impl-trait/in-trait/return-dont-satisfy-bounds.rs +++ b/tests/ui/impl-trait/in-trait/return-dont-satisfy-bounds.rs @@ -9,6 +9,7 @@ impl Foo<char> for Bar { //~^ ERROR: the trait bound `impl Foo<u8>: Foo<char>` is not satisfied [E0277] //~| ERROR: the trait bound `Bar: Foo<u8>` is not satisfied [E0277] //~| ERROR: impl has stricter requirements than trait + //~| ERROR: the trait bound `F2: Foo<u8>` is not satisfied self } } diff --git a/tests/ui/impl-trait/in-trait/return-dont-satisfy-bounds.stderr b/tests/ui/impl-trait/in-trait/return-dont-satisfy-bounds.stderr index 12725c3456f..fbf82a24b50 100644 --- a/tests/ui/impl-trait/in-trait/return-dont-satisfy-bounds.stderr +++ b/tests/ui/impl-trait/in-trait/return-dont-satisfy-bounds.stderr @@ -11,6 +11,22 @@ note: required by a bound in `Foo::{synthetic#0}` LL | fn foo<F2>(self) -> impl Foo<T>; | ^^^^^^ required by this bound in `Foo::{synthetic#0}` +error[E0277]: the trait bound `F2: Foo<u8>` is not satisfied + --> $DIR/return-dont-satisfy-bounds.rs:8:34 + | +LL | fn foo<F2: Foo<u8>>(self) -> impl Foo<u8> { + | ^^^^^^^^^^^^ the trait `Foo<u8>` is not implemented for `F2` + | +note: required by a bound in `<Bar as Foo<char>>::foo` + --> $DIR/return-dont-satisfy-bounds.rs:8:16 + | +LL | fn foo<F2: Foo<u8>>(self) -> impl Foo<u8> { + | ^^^^^^^ required by this bound in `<Bar as Foo<char>>::foo` +help: consider further restricting this bound + | +LL | fn foo<F2: Foo<u8> + Foo<u8>>(self) -> impl Foo<u8> { + | +++++++++ + error[E0276]: impl has stricter requirements than trait --> $DIR/return-dont-satisfy-bounds.rs:8:16 | @@ -32,7 +48,7 @@ LL | self = help: the trait `Foo<char>` is implemented for `Bar` = help: for that trait implementation, expected `char`, found `u8` -error: aborting due to 3 previous errors +error: aborting due to 4 previous errors Some errors have detailed explanations: E0276, E0277. For more information about an error, try `rustc --explain E0276`. diff --git a/tests/ui/impl-trait/stranded-opaque.rs b/tests/ui/impl-trait/stranded-opaque.rs new file mode 100644 index 00000000000..c7ab390e1fd --- /dev/null +++ b/tests/ui/impl-trait/stranded-opaque.rs @@ -0,0 +1,13 @@ +trait Trait {} + +impl Trait for i32 {} + +// Since `Assoc` doesn't actually exist, it's "stranded", and won't show up in +// the list of opaques that may be defined by the function. Make sure we don't +// ICE in this case. +fn produce<T>() -> impl Trait<Assoc = impl Trait> { + //~^ ERROR associated type `Assoc` not found for `Trait` + 16 +} + +fn main () {} diff --git a/tests/ui/impl-trait/stranded-opaque.stderr b/tests/ui/impl-trait/stranded-opaque.stderr new file mode 100644 index 00000000000..75f5480bc8b --- /dev/null +++ b/tests/ui/impl-trait/stranded-opaque.stderr @@ -0,0 +1,9 @@ +error[E0220]: associated type `Assoc` not found for `Trait` + --> $DIR/stranded-opaque.rs:8:31 + | +LL | fn produce<T>() -> impl Trait<Assoc = impl Trait> { + | ^^^^^ associated type `Assoc` not found + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0220`. diff --git a/tests/ui/implied-bounds/gluon_salsa.rs b/tests/ui/implied-bounds/gluon_salsa.rs index 368fb197909..cc6352c4a32 100644 --- a/tests/ui/implied-bounds/gluon_salsa.rs +++ b/tests/ui/implied-bounds/gluon_salsa.rs @@ -1,5 +1,6 @@ //@ check-pass -// Found in a crater run on #118553 +// Related to Bevy regression #115559, found in +// a crater run on #118553. pub trait QueryBase { type Db; @@ -17,11 +18,17 @@ pub struct QueryTable<'me, Q, DB> { _marker: Option<&'me ()>, } -impl<'me, Q> QueryTable<'me, Q, <Q as QueryBase>::Db> // projection is important -// ^^^ removing 'me (and in QueryTable) gives a different error +impl<'me, Q> QueryTable<'me, Q, <Q as QueryBase>::Db> where Q: for<'f> AsyncQueryFunction<'f>, { + // When borrowchechking this function we normalize `<Q as QueryBase>::Db` in the + // function signature to `<Self as QueryFunction<'?x>>::SendDb`, where `'?x` is an + // unconstrained region variable. We then addd `<Self as QueryFunction<'?x>>::SendDb: 'a` + // as an implied bound. We currently a structural equality to decide whether this bound + // should be used to prove the bound `<Self as QueryFunction<'?x>>::SendDb: 'a`. For this + // to work we may have to structurally resolve regions as the actually used vars may + // otherwise be semantically equal but structurally different. pub fn get_async<'a>(&'a mut self) { panic!(); } diff --git a/tests/ui/inline-const/const-expr-generic-err.stderr b/tests/ui/inline-const/const-expr-generic-err.stderr index fc0b6cc4451..7331c7f18e9 100644 --- a/tests/ui/inline-const/const-expr-generic-err.stderr +++ b/tests/ui/inline-const/const-expr-generic-err.stderr @@ -6,6 +6,12 @@ LL | const { assert!(std::mem::size_of::<T>() == 0); } | = note: this error originates in the macro `assert` (in Nightly builds, run with -Z macro-backtrace for more info) +note: erroneous constant encountered + --> $DIR/const-expr-generic-err.rs:5:5 + | +LL | const { assert!(std::mem::size_of::<T>() == 0); } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + note: the above error was encountered while instantiating `fn foo::<i32>` --> $DIR/const-expr-generic-err.rs:13:5 | @@ -18,6 +24,20 @@ error[E0080]: evaluation of `bar::<0>::{constant#0}` failed LL | const { N - 1 } | ^^^^^ attempt to compute `0_usize - 1_usize`, which would overflow +note: erroneous constant encountered + --> $DIR/const-expr-generic-err.rs:9:5 + | +LL | const { N - 1 } + | ^^^^^^^^^^^^^^^ + +note: erroneous constant encountered + --> $DIR/const-expr-generic-err.rs:9:5 + | +LL | const { N - 1 } + | ^^^^^^^^^^^^^^^ + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + note: the above error was encountered while instantiating `fn bar::<0>` --> $DIR/const-expr-generic-err.rs:14:5 | diff --git a/tests/ui/inline-const/required-const.stderr b/tests/ui/inline-const/required-const.stderr index cd86020184d..2a13d18547c 100644 --- a/tests/ui/inline-const/required-const.stderr +++ b/tests/ui/inline-const/required-const.stderr @@ -6,6 +6,12 @@ LL | const { 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 encountered + --> $DIR/required-const.rs:7:9 + | +LL | const { panic!() } + | ^^^^^^^^^^^^^^^^^^ + error: aborting due to 1 previous error For more information about this error, try `rustc --explain E0080`. diff --git a/tests/ui/lifetimes/issue-105675.rs b/tests/ui/lifetimes/issue-105675.rs index 58d8be8b65f..2e2eaca0d33 100644 --- a/tests/ui/lifetimes/issue-105675.rs +++ b/tests/ui/lifetimes/issue-105675.rs @@ -3,12 +3,12 @@ fn thing(x: impl FnOnce(&u32, &u32, u32)) {} fn main() { let f = | _ , y: &u32 , z | (); thing(f); - //~^ ERROR mismatched types - //~^^ ERROR mismatched types + //~^ ERROR implementation of `FnOnce` is not general enough + //~^^ ERROR implementation of `FnOnce` is not general enough let f = | x, y: _ , z: u32 | (); thing(f); - //~^ ERROR mismatched types - //~^^ ERROR mismatched types - //~^^^ ERROR implementation of `FnOnce` is not general enough - //~^^^^ ERROR implementation of `FnOnce` is not general enough + //~^ ERROR implementation of `FnOnce` is not general enough + //~| ERROR implementation of `FnOnce` is not general enough + //~| ERROR implementation of `FnOnce` is not general enough + //~| ERROR implementation of `FnOnce` is not general enough } diff --git a/tests/ui/lifetimes/issue-105675.stderr b/tests/ui/lifetimes/issue-105675.stderr index f1fa5a59860..4b3d0e8ac5e 100644 --- a/tests/ui/lifetimes/issue-105675.stderr +++ b/tests/ui/lifetimes/issue-105675.stderr @@ -1,91 +1,39 @@ -error[E0308]: mismatched types +error: implementation of `FnOnce` is not general enough --> $DIR/issue-105675.rs:5:5 | LL | thing(f); - | ^^^^^^^^ one type is more general than the other - | - = note: expected trait `for<'a, 'b> FnOnce(&'a u32, &'b u32, u32)` - found trait `for<'a> FnOnce(&u32, &'a u32, u32)` -note: this closure does not fulfill the lifetime requirements - --> $DIR/issue-105675.rs:4:13 - | -LL | let f = | _ , y: &u32 , z | (); - | ^^^^^^^^^^^^^^^^^^^ -note: the lifetime requirement is introduced here - --> $DIR/issue-105675.rs:1:18 - | -LL | fn thing(x: impl FnOnce(&u32, &u32, u32)) {} - | ^^^^^^^^^^^^^^^^^^^^^^^ -help: consider specifying the type of the closure parameters + | ^^^^^^^^ implementation of `FnOnce` is not general enough | -LL | let f = |_: &_, y: &u32, z| (); - | ~~~~~~~~~~~~~~~~~~~ + = note: closure with signature `for<'a> fn(&'2 u32, &'a u32, u32)` must implement `FnOnce<(&'1 u32, &u32, u32)>`, for any lifetime `'1`... + = note: ...but it actually implements `FnOnce<(&'2 u32, &u32, u32)>`, for some specific lifetime `'2` -error[E0308]: mismatched types +error: implementation of `FnOnce` is not general enough --> $DIR/issue-105675.rs:5:5 | LL | thing(f); - | ^^^^^^^^ one type is more general than the other - | - = note: expected trait `for<'a, 'b> FnOnce(&'a u32, &'b u32, u32)` - found trait `for<'a> FnOnce(&u32, &'a u32, u32)` -note: this closure does not fulfill the lifetime requirements - --> $DIR/issue-105675.rs:4:13 - | -LL | let f = | _ , y: &u32 , z | (); - | ^^^^^^^^^^^^^^^^^^^ -note: the lifetime requirement is introduced here - --> $DIR/issue-105675.rs:1:18 + | ^^^^^^^^ implementation of `FnOnce` is not general enough | -LL | fn thing(x: impl FnOnce(&u32, &u32, u32)) {} - | ^^^^^^^^^^^^^^^^^^^^^^^ + = note: closure with signature `for<'a> fn(&'2 u32, &'a u32, u32)` must implement `FnOnce<(&'1 u32, &u32, u32)>`, for any lifetime `'1`... + = note: ...but it actually implements `FnOnce<(&'2 u32, &u32, u32)>`, for some specific lifetime `'2` + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` -error[E0308]: mismatched types +error: implementation of `FnOnce` is not general enough --> $DIR/issue-105675.rs:9:5 | LL | thing(f); - | ^^^^^^^^ one type is more general than the other - | - = note: expected trait `for<'a, 'b> FnOnce(&'a u32, &'b u32, u32)` - found trait `FnOnce(&u32, &u32, u32)` -note: this closure does not fulfill the lifetime requirements - --> $DIR/issue-105675.rs:8:13 - | -LL | let f = | x, y: _ , z: u32 | (); - | ^^^^^^^^^^^^^^^^^^^^^ -note: the lifetime requirement is introduced here - --> $DIR/issue-105675.rs:1:18 - | -LL | fn thing(x: impl FnOnce(&u32, &u32, u32)) {} - | ^^^^^^^^^^^^^^^^^^^^^^^ -help: consider specifying the type of the closure parameters + | ^^^^^^^^ implementation of `FnOnce` is not general enough | -LL | let f = |x: &_, y: &_, z: u32| (); - | ~~~~~~~~~~~~~~~~~~~~~~ + = note: closure with signature `fn(&'2 u32, &u32, u32)` must implement `FnOnce<(&'1 u32, &u32, u32)>`, for any lifetime `'1`... + = note: ...but it actually implements `FnOnce<(&'2 u32, &u32, u32)>`, for some specific lifetime `'2` -error[E0308]: mismatched types +error: implementation of `FnOnce` is not general enough --> $DIR/issue-105675.rs:9:5 | LL | thing(f); - | ^^^^^^^^ one type is more general than the other - | - = note: expected trait `for<'a, 'b> FnOnce(&'a u32, &'b u32, u32)` - found trait `FnOnce(&u32, &u32, u32)` -note: this closure does not fulfill the lifetime requirements - --> $DIR/issue-105675.rs:8:13 - | -LL | let f = | x, y: _ , z: u32 | (); - | ^^^^^^^^^^^^^^^^^^^^^ -note: the lifetime requirement is introduced here - --> $DIR/issue-105675.rs:1:18 - | -LL | fn thing(x: impl FnOnce(&u32, &u32, u32)) {} - | ^^^^^^^^^^^^^^^^^^^^^^^ - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` -help: consider specifying the type of the closure parameters + | ^^^^^^^^ implementation of `FnOnce` is not general enough | -LL | let f = |x: &_, y: &_, z: u32| (); - | ~~~~~~~~~~~~~~~~~~~~~~ + = note: closure with signature `fn(&u32, &'2 u32, u32)` must implement `FnOnce<(&u32, &'1 u32, u32)>`, for any lifetime `'1`... + = note: ...but it actually implements `FnOnce<(&u32, &'2 u32, u32)>`, for some specific lifetime `'2` error: implementation of `FnOnce` is not general enough --> $DIR/issue-105675.rs:9:5 @@ -95,6 +43,7 @@ LL | thing(f); | = note: closure with signature `fn(&'2 u32, &u32, u32)` must implement `FnOnce<(&'1 u32, &u32, u32)>`, for any lifetime `'1`... = note: ...but it actually implements `FnOnce<(&'2 u32, &u32, u32)>`, for some specific lifetime `'2` + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error: implementation of `FnOnce` is not general enough --> $DIR/issue-105675.rs:9:5 @@ -104,7 +53,7 @@ LL | thing(f); | = note: closure with signature `fn(&u32, &'2 u32, u32)` must implement `FnOnce<(&u32, &'1 u32, u32)>`, for any lifetime `'1`... = note: ...but it actually implements `FnOnce<(&u32, &'2 u32, u32)>`, for some specific lifetime `'2` + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error: aborting due to 6 previous errors -For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/lifetimes/issue-76168-hr-outlives-3.rs b/tests/ui/lifetimes/issue-76168-hr-outlives-3.rs index 85eeb5d4c90..eab436fa341 100644 --- a/tests/ui/lifetimes/issue-76168-hr-outlives-3.rs +++ b/tests/ui/lifetimes/issue-76168-hr-outlives-3.rs @@ -7,6 +7,7 @@ async fn wrapper<F>(f: F) //~^ ERROR: expected a `FnOnce(&'a mut i32)` closure, found `i32` //~| ERROR: expected a `FnOnce(&'a mut i32)` closure, found `i32` //~| ERROR: expected a `FnOnce(&'a mut i32)` closure, found `i32` +//~| ERROR: expected a `FnOnce(&'a mut i32)` closure, found `i32` where F:, for<'a> <i32 as FnOnce<(&'a mut i32,)>>::Output: Future<Output = ()> + 'a, diff --git a/tests/ui/lifetimes/issue-76168-hr-outlives-3.stderr b/tests/ui/lifetimes/issue-76168-hr-outlives-3.stderr index 578ba149baf..e9f97d1d93b 100644 --- a/tests/ui/lifetimes/issue-76168-hr-outlives-3.stderr +++ b/tests/ui/lifetimes/issue-76168-hr-outlives-3.stderr @@ -5,7 +5,7 @@ LL | / async fn wrapper<F>(f: F) LL | | LL | | LL | | -LL | | where +... | LL | | F:, LL | | for<'a> <i32 as FnOnce<(&'a mut i32,)>>::Output: Future<Output = ()> + 'a, | |__________________________________________________________________________^ expected an `FnOnce(&'a mut i32)` closure, found `i32` @@ -27,7 +27,7 @@ LL | / async fn wrapper<F>(f: F) LL | | LL | | LL | | -LL | | where +... | LL | | F:, LL | | for<'a> <i32 as FnOnce<(&'a mut i32,)>>::Output: Future<Output = ()> + 'a, | |__________________________________________________________________________^ expected an `FnOnce(&'a mut i32)` closure, found `i32` @@ -35,7 +35,22 @@ LL | | for<'a> <i32 as FnOnce<(&'a mut i32,)>>::Output: Future<Output = ()> + 'a = help: the trait `for<'a> FnOnce<(&'a mut i32,)>` is not implemented for `i32` error[E0277]: expected a `FnOnce(&'a mut i32)` closure, found `i32` - --> $DIR/issue-76168-hr-outlives-3.rs:13:1 + --> $DIR/issue-76168-hr-outlives-3.rs:6:1 + | +LL | / async fn wrapper<F>(f: F) +LL | | +LL | | +LL | | +... | +LL | | F:, +LL | | for<'a> <i32 as FnOnce<(&'a mut i32,)>>::Output: Future<Output = ()> + 'a, + | |__________________________________________________________________________^ expected an `FnOnce(&'a mut i32)` closure, found `i32` + | + = help: the trait `for<'a> FnOnce<(&'a mut i32,)>` is not implemented for `i32` + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +error[E0277]: expected a `FnOnce(&'a mut i32)` closure, found `i32` + --> $DIR/issue-76168-hr-outlives-3.rs:14:1 | LL | / { LL | | @@ -46,6 +61,6 @@ LL | | } | = help: the trait `for<'a> FnOnce<(&'a mut i32,)>` is not implemented for `i32` -error: aborting due to 4 previous errors +error: aborting due to 5 previous errors For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/lifetimes/issue-79187-2.rs b/tests/ui/lifetimes/issue-79187-2.rs index fff92c30b37..9d7f17e7f23 100644 --- a/tests/ui/lifetimes/issue-79187-2.rs +++ b/tests/ui/lifetimes/issue-79187-2.rs @@ -7,7 +7,7 @@ fn take_foo(_: impl Foo) {} fn main() { take_foo(|a| a); //~^ ERROR implementation of `FnOnce` is not general enough - //~| ERROR mismatched types + //~| ERROR implementation of `Fn` is not general enough take_foo(|a: &i32| a); //~^ ERROR lifetime may not live long enough //~| ERROR mismatched types diff --git a/tests/ui/lifetimes/issue-79187-2.stderr b/tests/ui/lifetimes/issue-79187-2.stderr index e8115bb6b06..78f6ce882df 100644 --- a/tests/ui/lifetimes/issue-79187-2.stderr +++ b/tests/ui/lifetimes/issue-79187-2.stderr @@ -25,28 +25,14 @@ LL | take_foo(|a| a); = note: closure with signature `fn(&'2 i32) -> &i32` must implement `FnOnce<(&'1 i32,)>`, for any lifetime `'1`... = note: ...but it actually implements `FnOnce<(&'2 i32,)>`, for some specific lifetime `'2` -error[E0308]: mismatched types +error: implementation of `Fn` is not general enough --> $DIR/issue-79187-2.rs:8:5 | LL | take_foo(|a| a); - | ^^^^^^^^^^^^^^^ one type is more general than the other - | - = note: expected trait `for<'a> Fn(&'a i32)` - found trait `Fn(&i32)` -note: this closure does not fulfill the lifetime requirements - --> $DIR/issue-79187-2.rs:8:14 - | -LL | take_foo(|a| a); - | ^^^ -note: the lifetime requirement is introduced here - --> $DIR/issue-79187-2.rs:5:21 - | -LL | fn take_foo(_: impl Foo) {} - | ^^^ -help: consider specifying the type of the closure parameters + | ^^^^^^^^^^^^^^^ implementation of `Fn` is not general enough | -LL | take_foo(|a: &_| a); - | ~~~~~~~ + = note: closure with signature `fn(&'2 i32) -> &i32` must implement `Fn<(&'1 i32,)>`, for any lifetime `'1`... + = note: ...but it actually implements `Fn<(&'2 i32,)>`, for some specific lifetime `'2` error[E0308]: mismatched types --> $DIR/issue-79187-2.rs:11:5 diff --git a/tests/ui/lifetimes/issue-79187.rs b/tests/ui/lifetimes/issue-79187.rs index 8e13045623b..a8829bd4e49 100644 --- a/tests/ui/lifetimes/issue-79187.rs +++ b/tests/ui/lifetimes/issue-79187.rs @@ -3,6 +3,6 @@ fn thing(x: impl FnOnce(&u32)) {} fn main() { let f = |_| (); thing(f); - //~^ ERROR mismatched types - //~^^ ERROR implementation of `FnOnce` is not general enough + //~^ ERROR implementation of `FnOnce` is not general enough + //~| ERROR implementation of `FnOnce` is not general enough } diff --git a/tests/ui/lifetimes/issue-79187.stderr b/tests/ui/lifetimes/issue-79187.stderr index 14bdfe75c08..8adde8d6dfb 100644 --- a/tests/ui/lifetimes/issue-79187.stderr +++ b/tests/ui/lifetimes/issue-79187.stderr @@ -1,25 +1,11 @@ -error[E0308]: mismatched types +error: implementation of `FnOnce` is not general enough --> $DIR/issue-79187.rs:5:5 | LL | thing(f); - | ^^^^^^^^ one type is more general than the other - | - = note: expected trait `for<'a> FnOnce(&'a u32)` - found trait `FnOnce(&u32)` -note: this closure does not fulfill the lifetime requirements - --> $DIR/issue-79187.rs:4:13 - | -LL | let f = |_| (); - | ^^^ -note: the lifetime requirement is introduced here - --> $DIR/issue-79187.rs:1:18 - | -LL | fn thing(x: impl FnOnce(&u32)) {} - | ^^^^^^^^^^^^ -help: consider specifying the type of the closure parameters + | ^^^^^^^^ implementation of `FnOnce` is not general enough | -LL | let f = |_: &_| (); - | ~~~~~~~ + = note: closure with signature `fn(&'2 u32)` must implement `FnOnce<(&'1 u32,)>`, for any lifetime `'1`... + = note: ...but it actually implements `FnOnce<(&'2 u32,)>`, for some specific lifetime `'2` error: implementation of `FnOnce` is not general enough --> $DIR/issue-79187.rs:5:5 @@ -29,7 +15,7 @@ LL | thing(f); | = note: closure with signature `fn(&'2 u32)` must implement `FnOnce<(&'1 u32,)>`, for any lifetime `'1`... = note: ...but it actually implements `FnOnce<(&'2 u32,)>`, for some specific lifetime `'2` + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error: aborting due to 2 previous errors -For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/lifetimes/lifetime-errors/issue_74400.rs b/tests/ui/lifetimes/lifetime-errors/issue_74400.rs index f17e0a678c9..b02e38bec3b 100644 --- a/tests/ui/lifetimes/lifetime-errors/issue_74400.rs +++ b/tests/ui/lifetimes/lifetime-errors/issue_74400.rs @@ -13,6 +13,6 @@ fn g<T>(data: &[T]) { //~^ ERROR the parameter type //~| ERROR the parameter type //~| ERROR the parameter type - //~| ERROR mismatched types //~| ERROR implementation of `FnOnce` is not general + //~| ERROR implementation of `Fn` is not general enough } diff --git a/tests/ui/lifetimes/lifetime-errors/issue_74400.stderr b/tests/ui/lifetimes/lifetime-errors/issue_74400.stderr index beb838d2ff8..4dada6ff014 100644 --- a/tests/ui/lifetimes/lifetime-errors/issue_74400.stderr +++ b/tests/ui/lifetimes/lifetime-errors/issue_74400.stderr @@ -42,19 +42,14 @@ help: consider adding an explicit lifetime bound LL | fn g<T: 'static>(data: &[T]) { | +++++++++ -error[E0308]: mismatched types +error: implementation of `Fn` is not general enough --> $DIR/issue_74400.rs:12:5 | LL | f(data, identity) - | ^^^^^^^^^^^^^^^^^ one type is more general than the other + | ^^^^^^^^^^^^^^^^^ implementation of `Fn` is not general enough | - = note: expected trait `for<'a> Fn(&'a T)` - found trait `Fn(&T)` -note: the lifetime requirement is introduced here - --> $DIR/issue_74400.rs:8:34 - | -LL | fn f<T, S>(data: &[T], key: impl Fn(&T) -> S) { - | ^^^^^^^^^^^ + = note: `fn(&'2 T) -> &'2 T {identity::<&'2 T>}` must implement `Fn<(&'1 T,)>`, for any lifetime `'1`... + = note: ...but it actually implements `Fn<(&'2 T,)>`, for some specific lifetime `'2` error: implementation of `FnOnce` is not general enough --> $DIR/issue_74400.rs:12:5 @@ -67,5 +62,4 @@ LL | f(data, identity) error: aborting due to 5 previous errors -Some errors have detailed explanations: E0308, E0310. -For more information about an error, try `rustc --explain E0308`. +For more information about this error, try `rustc --explain E0310`. diff --git a/tests/ui/lint/lint-qualification.fixed b/tests/ui/lint/lint-qualification.fixed index 2b1f8b59175..6fe6ba2792f 100644 --- a/tests/ui/lint/lint-qualification.fixed +++ b/tests/ui/lint/lint-qualification.fixed @@ -1,5 +1,6 @@ //@ run-rustfix #![deny(unused_qualifications)] +#![deny(unused_imports)] #![allow(deprecated, dead_code)] mod foo { @@ -21,8 +22,10 @@ fn main() { //~^ ERROR: unnecessary qualification //~| ERROR: unnecessary qualification - use std::fmt; - let _: fmt::Result = Ok(()); //~ ERROR: unnecessary qualification + + //~^ ERROR: unused import: `std::fmt` + let _: std::fmt::Result = Ok(()); + // don't report unnecessary qualification because fix(#122373) for issue #121331 let _ = <bool as Default>::default(); // issue #121999 //~^ ERROR: unnecessary qualification diff --git a/tests/ui/lint/lint-qualification.rs b/tests/ui/lint/lint-qualification.rs index 002fdbf7724..19d339b006c 100644 --- a/tests/ui/lint/lint-qualification.rs +++ b/tests/ui/lint/lint-qualification.rs @@ -1,5 +1,6 @@ //@ run-rustfix #![deny(unused_qualifications)] +#![deny(unused_imports)] #![allow(deprecated, dead_code)] mod foo { @@ -22,7 +23,9 @@ fn main() { //~| ERROR: unnecessary qualification use std::fmt; - let _: std::fmt::Result = Ok(()); //~ ERROR: unnecessary qualification + //~^ ERROR: unused import: `std::fmt` + let _: std::fmt::Result = Ok(()); + // don't report unnecessary qualification because fix(#122373) for issue #121331 let _ = <bool as ::std::default::Default>::default(); // issue #121999 //~^ ERROR: unnecessary qualification diff --git a/tests/ui/lint/lint-qualification.stderr b/tests/ui/lint/lint-qualification.stderr index 8dddcf23f75..9e5c9b2df13 100644 --- a/tests/ui/lint/lint-qualification.stderr +++ b/tests/ui/lint/lint-qualification.stderr @@ -1,5 +1,5 @@ error: unnecessary qualification - --> $DIR/lint-qualification.rs:11:5 + --> $DIR/lint-qualification.rs:12:5 | LL | foo::bar(); | ^^^^^^^^ @@ -16,7 +16,7 @@ LL + bar(); | error: unnecessary qualification - --> $DIR/lint-qualification.rs:12:5 + --> $DIR/lint-qualification.rs:13:5 | LL | crate::foo::bar(); | ^^^^^^^^^^^^^^^ @@ -28,7 +28,7 @@ LL + bar(); | error: unnecessary qualification - --> $DIR/lint-qualification.rs:17:13 + --> $DIR/lint-qualification.rs:18:13 | LL | let _ = std::string::String::new(); | ^^^^^^^^^^^^^^^^^^^^^^^^ @@ -40,7 +40,7 @@ LL + let _ = String::new(); | error: unnecessary qualification - --> $DIR/lint-qualification.rs:18:13 + --> $DIR/lint-qualification.rs:19:13 | LL | let _ = ::std::env::current_dir(); | ^^^^^^^^^^^^^^^^^^^^^^^ @@ -52,7 +52,7 @@ LL + let _ = std::env::current_dir(); | error: unnecessary qualification - --> $DIR/lint-qualification.rs:20:12 + --> $DIR/lint-qualification.rs:21:12 | LL | let _: std::vec::Vec<String> = std::vec::Vec::<String>::new(); | ^^^^^^^^^^^^^^^^^^^^^ @@ -64,7 +64,7 @@ LL + let _: Vec<String> = std::vec::Vec::<String>::new(); | error: unnecessary qualification - --> $DIR/lint-qualification.rs:20:36 + --> $DIR/lint-qualification.rs:21:36 | LL | let _: std::vec::Vec<String> = std::vec::Vec::<String>::new(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -75,20 +75,20 @@ LL - let _: std::vec::Vec<String> = std::vec::Vec::<String>::new(); LL + let _: std::vec::Vec<String> = Vec::<String>::new(); | -error: unnecessary qualification - --> $DIR/lint-qualification.rs:25:12 - | -LL | let _: std::fmt::Result = Ok(()); - | ^^^^^^^^^^^^^^^^ +error: unused import: `std::fmt` + --> $DIR/lint-qualification.rs:25:9 | -help: remove the unnecessary path segments +LL | use std::fmt; + | ^^^^^^^^ | -LL - let _: std::fmt::Result = Ok(()); -LL + let _: fmt::Result = Ok(()); +note: the lint level is defined here + --> $DIR/lint-qualification.rs:3:9 | +LL | #![deny(unused_imports)] + | ^^^^^^^^^^^^^^ error: unnecessary qualification - --> $DIR/lint-qualification.rs:27:13 + --> $DIR/lint-qualification.rs:30:13 | LL | let _ = <bool as ::std::default::Default>::default(); // issue #121999 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/lint/unnecessary-qualification/lint-unnecessary-qualification-issue-121331.fixed b/tests/ui/lint/unnecessary-qualification/lint-unnecessary-qualification-issue-121331.fixed new file mode 100644 index 00000000000..d554bbfcc98 --- /dev/null +++ b/tests/ui/lint/unnecessary-qualification/lint-unnecessary-qualification-issue-121331.fixed @@ -0,0 +1,50 @@ +//@ run-rustfix +//@ edition:2021 +#![deny(unused_qualifications)] +#![deny(unused_imports)] +#![feature(coroutines, coroutine_trait)] + +use std::ops::{ + Coroutine, + CoroutineState::{self}, + //~^ ERROR unused import: `*` +}; +use std::pin::Pin; + +#[allow(dead_code)] +fn finish<T>(mut amt: usize, mut t: T) -> T::Return + where T: Coroutine<(), Yield = ()> + Unpin, +{ + loop { + match Pin::new(&mut t).resume(()) { + CoroutineState::Yielded(()) => amt = amt.checked_sub(1).unwrap(), + CoroutineState::Complete(ret) => { + assert_eq!(amt, 0); + return ret + } + } + } +} + + +mod foo { + pub fn bar() {} +} + +pub fn main() { + + use foo::bar; + bar(); + //~^ ERROR unnecessary qualification + bar(); + + // The item `use std::string::String` is imported redundantly. + // Suppress `unused_imports` reporting, otherwise the fixed file will report an error + #[allow(unused_imports)] + use std::string::String; + let s = String::new(); + let y = std::string::String::new(); + // unnecessary qualification + println!("{} {}", s, y); + +} diff --git a/tests/ui/lint/unnecessary-qualification/lint-unnecessary-qualification-issue-121331.rs b/tests/ui/lint/unnecessary-qualification/lint-unnecessary-qualification-issue-121331.rs new file mode 100644 index 00000000000..4d79f5ab745 --- /dev/null +++ b/tests/ui/lint/unnecessary-qualification/lint-unnecessary-qualification-issue-121331.rs @@ -0,0 +1,50 @@ +//@ run-rustfix +//@ edition:2021 +#![deny(unused_qualifications)] +#![deny(unused_imports)] +#![feature(coroutines, coroutine_trait)] + +use std::ops::{ + Coroutine, + CoroutineState::{self, *}, + //~^ ERROR unused import: `*` +}; +use std::pin::Pin; + +#[allow(dead_code)] +fn finish<T>(mut amt: usize, mut t: T) -> T::Return + where T: Coroutine<(), Yield = ()> + Unpin, +{ + loop { + match Pin::new(&mut t).resume(()) { + CoroutineState::Yielded(()) => amt = amt.checked_sub(1).unwrap(), + CoroutineState::Complete(ret) => { + assert_eq!(amt, 0); + return ret + } + } + } +} + + +mod foo { + pub fn bar() {} +} + +pub fn main() { + + use foo::bar; + foo::bar(); + //~^ ERROR unnecessary qualification + bar(); + + // The item `use std::string::String` is imported redundantly. + // Suppress `unused_imports` reporting, otherwise the fixed file will report an error + #[allow(unused_imports)] + use std::string::String; + let s = String::new(); + let y = std::string::String::new(); + // unnecessary qualification + println!("{} {}", s, y); + +} diff --git a/tests/ui/lint/unnecessary-qualification/lint-unnecessary-qualification-issue-121331.stderr b/tests/ui/lint/unnecessary-qualification/lint-unnecessary-qualification-issue-121331.stderr new file mode 100644 index 00000000000..52ed13ea150 --- /dev/null +++ b/tests/ui/lint/unnecessary-qualification/lint-unnecessary-qualification-issue-121331.stderr @@ -0,0 +1,31 @@ +error: unused import: `*` + --> $DIR/lint-unnecessary-qualification-issue-121331.rs:9:28 + | +LL | CoroutineState::{self, *}, + | ^ + | +note: the lint level is defined here + --> $DIR/lint-unnecessary-qualification-issue-121331.rs:4:9 + | +LL | #![deny(unused_imports)] + | ^^^^^^^^^^^^^^ + +error: unnecessary qualification + --> $DIR/lint-unnecessary-qualification-issue-121331.rs:37:5 + | +LL | foo::bar(); + | ^^^^^^^^ + | +note: the lint level is defined here + --> $DIR/lint-unnecessary-qualification-issue-121331.rs:3:9 + | +LL | #![deny(unused_qualifications)] + | ^^^^^^^^^^^^^^^^^^^^^ +help: remove the unnecessary path segments + | +LL - foo::bar(); +LL + bar(); + | + +error: aborting due to 2 previous errors + diff --git a/tests/ui/mismatched_types/closure-arg-type-mismatch-issue-45727.stderr b/tests/ui/mismatched_types/closure-arg-type-mismatch-issue-45727.stderr index 452cba6b4de..e52e095e9f7 100644 --- a/tests/ui/mismatched_types/closure-arg-type-mismatch-issue-45727.stderr +++ b/tests/ui/mismatched_types/closure-arg-type-mismatch-issue-45727.stderr @@ -24,7 +24,7 @@ LL | let _ = (-10..=10).find(|x: &&&i32| x.signum() == 0); | expected due to this | = note: expected closure signature `for<'a> fn(&'a {integer}) -> _` - found closure signature `for<'a, 'b, 'c> fn(&'a &'b &'c i32) -> _` + found closure signature `fn(&&&i32) -> _` note: required by a bound in `find` --> $SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL help: consider adjusting the signature so it does not borrow its argument diff --git a/tests/ui/mismatched_types/closure-arg-type-mismatch.rs b/tests/ui/mismatched_types/closure-arg-type-mismatch.rs index e73a33dfded..55a4a0b5707 100644 --- a/tests/ui/mismatched_types/closure-arg-type-mismatch.rs +++ b/tests/ui/mismatched_types/closure-arg-type-mismatch.rs @@ -8,7 +8,7 @@ fn main() { fn baz<F: Fn(*mut &u32)>(_: F) {} fn _test<'a>(f: fn(*mut &'a u32)) { baz(f); - //~^ ERROR: mismatched types + //~^ ERROR: implementation of `FnOnce` is not general enough //~| ERROR: borrowed data escapes //~| ERROR: not general enough } diff --git a/tests/ui/mismatched_types/closure-arg-type-mismatch.stderr b/tests/ui/mismatched_types/closure-arg-type-mismatch.stderr index e63d3f6a075..abc5d150a3f 100644 --- a/tests/ui/mismatched_types/closure-arg-type-mismatch.stderr +++ b/tests/ui/mismatched_types/closure-arg-type-mismatch.stderr @@ -24,7 +24,7 @@ LL | a.iter().map(|_: &(u16, u16)| 45); | expected due to this | = note: expected closure signature `fn(&(u32, u32)) -> _` - found closure signature `for<'a> fn(&'a (u16, u16)) -> _` + found closure signature `fn(&(u16, u16)) -> _` note: required by a bound in `map` --> $SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL @@ -63,19 +63,14 @@ note: due to current limitations in the borrow checker, this implies a `'static` LL | fn baz<F: Fn(*mut &u32)>(_: F) {} | ^^^^^^^^^^^^^ -error[E0308]: mismatched types +error: implementation of `Fn` is not general enough --> $DIR/closure-arg-type-mismatch.rs:10:5 | LL | baz(f); - | ^^^^^^ one type is more general than the other + | ^^^^^^ implementation of `Fn` is not general enough | - = note: expected trait `for<'a> Fn(*mut &'a u32)` - found trait `Fn(*mut &u32)` -note: the lifetime requirement is introduced here - --> $DIR/closure-arg-type-mismatch.rs:8:11 - | -LL | fn baz<F: Fn(*mut &u32)>(_: F) {} - | ^^^^^^^^^^^^^ + = note: `fn(*mut &'2 u32)` must implement `Fn<(*mut &'1 u32,)>`, for any lifetime `'1`... + = note: ...but it actually implements `Fn<(*mut &'2 u32,)>`, for some specific lifetime `'2` error: implementation of `FnOnce` is not general enough --> $DIR/closure-arg-type-mismatch.rs:10:5 @@ -88,5 +83,5 @@ LL | baz(f); error: aborting due to 6 previous errors -Some errors have detailed explanations: E0308, E0521, E0631. -For more information about an error, try `rustc --explain E0308`. +Some errors have detailed explanations: E0521, E0631. +For more information about an error, try `rustc --explain E0521`. diff --git a/tests/ui/mismatched_types/closure-mismatch.rs b/tests/ui/mismatched_types/closure-mismatch.rs index 4eb33497c39..efaed4dc1b9 100644 --- a/tests/ui/mismatched_types/closure-mismatch.rs +++ b/tests/ui/mismatched_types/closure-mismatch.rs @@ -7,8 +7,8 @@ fn baz<T: Foo>(_: T) {} fn main() { baz(|_| ()); //~^ ERROR implementation of `FnOnce` is not general enough - //~| ERROR mismatched types + //~| ERROR implementation of `Fn` is not general enough baz(|x| ()); //~^ ERROR implementation of `FnOnce` is not general enough - //~| ERROR mismatched types + //~| ERROR implementation of `Fn` is not general enough } diff --git a/tests/ui/mismatched_types/closure-mismatch.stderr b/tests/ui/mismatched_types/closure-mismatch.stderr index 74033c18573..802110c6511 100644 --- a/tests/ui/mismatched_types/closure-mismatch.stderr +++ b/tests/ui/mismatched_types/closure-mismatch.stderr @@ -7,28 +7,14 @@ LL | baz(|_| ()); = note: closure with signature `fn(&'2 ())` must implement `FnOnce<(&'1 (),)>`, for any lifetime `'1`... = note: ...but it actually implements `FnOnce<(&'2 (),)>`, for some specific lifetime `'2` -error[E0308]: mismatched types +error: implementation of `Fn` is not general enough --> $DIR/closure-mismatch.rs:8:5 | LL | baz(|_| ()); - | ^^^^^^^^^^^ one type is more general than the other + | ^^^^^^^^^^^ implementation of `Fn` is not general enough | - = note: expected trait `for<'a> Fn(&'a ())` - found trait `Fn(&())` -note: this closure does not fulfill the lifetime requirements - --> $DIR/closure-mismatch.rs:8:9 - | -LL | baz(|_| ()); - | ^^^ -note: the lifetime requirement is introduced here - --> $DIR/closure-mismatch.rs:5:11 - | -LL | fn baz<T: Foo>(_: T) {} - | ^^^ -help: consider specifying the type of the closure parameters - | -LL | baz(|_: &_| ()); - | ~~~~~~~ + = note: closure with signature `fn(&'2 ())` must implement `Fn<(&'1 (),)>`, for any lifetime `'1`... + = note: ...but it actually implements `Fn<(&'2 (),)>`, for some specific lifetime `'2` error: implementation of `FnOnce` is not general enough --> $DIR/closure-mismatch.rs:11:5 @@ -39,29 +25,14 @@ LL | baz(|x| ()); = note: closure with signature `fn(&'2 ())` must implement `FnOnce<(&'1 (),)>`, for any lifetime `'1`... = note: ...but it actually implements `FnOnce<(&'2 (),)>`, for some specific lifetime `'2` -error[E0308]: mismatched types +error: implementation of `Fn` is not general enough --> $DIR/closure-mismatch.rs:11:5 | LL | baz(|x| ()); - | ^^^^^^^^^^^ one type is more general than the other - | - = note: expected trait `for<'a> Fn(&'a ())` - found trait `Fn(&())` -note: this closure does not fulfill the lifetime requirements - --> $DIR/closure-mismatch.rs:11:9 - | -LL | baz(|x| ()); - | ^^^ -note: the lifetime requirement is introduced here - --> $DIR/closure-mismatch.rs:5:11 - | -LL | fn baz<T: Foo>(_: T) {} - | ^^^ -help: consider specifying the type of the closure parameters + | ^^^^^^^^^^^ implementation of `Fn` is not general enough | -LL | baz(|x: &_| ()); - | ~~~~~~~ + = note: closure with signature `fn(&'2 ())` must implement `Fn<(&'1 (),)>`, for any lifetime `'1`... + = note: ...but it actually implements `Fn<(&'2 (),)>`, for some specific lifetime `'2` error: aborting due to 4 previous errors -For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/mismatched_types/fn-variance-1.stderr b/tests/ui/mismatched_types/fn-variance-1.stderr index fdb2e6f0097..ed450d8d81c 100644 --- a/tests/ui/mismatched_types/fn-variance-1.stderr +++ b/tests/ui/mismatched_types/fn-variance-1.stderr @@ -10,7 +10,7 @@ LL | apply(&3, takes_mut); | required by a bound introduced by this call | = note: expected function signature `fn(&{integer}) -> _` - found function signature `for<'a> fn(&'a mut isize) -> _` + found function signature `fn(&mut isize) -> _` note: required by a bound in `apply` --> $DIR/fn-variance-1.rs:5:37 | @@ -33,7 +33,7 @@ LL | apply(&mut 3, takes_imm); | required by a bound introduced by this call | = note: expected function signature `fn(&mut {integer}) -> _` - found function signature `for<'a> fn(&'a isize) -> _` + found function signature `fn(&isize) -> _` note: required by a bound in `apply` --> $DIR/fn-variance-1.rs:5:37 | diff --git a/tests/ui/mismatched_types/issue-36053-2.stderr b/tests/ui/mismatched_types/issue-36053-2.stderr index 6d23319ca7e..ffaa276b62e 100644 --- a/tests/ui/mismatched_types/issue-36053-2.stderr +++ b/tests/ui/mismatched_types/issue-36053-2.stderr @@ -7,7 +7,7 @@ LL | once::<&str>("str").fuse().filter(|a: &str| true).count(); | expected due to this | = note: expected closure signature `for<'a> fn(&'a &_) -> _` - found closure signature `for<'a> fn(&'a _) -> _` + found closure signature `fn(&_) -> _` note: required by a bound in `filter` --> $SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL help: consider adjusting the signature so it borrows its argument diff --git a/tests/ui/mismatched_types/suggest-option-asderef-inference-var.stderr b/tests/ui/mismatched_types/suggest-option-asderef-inference-var.stderr index 0ed57466e9c..0b8943898f5 100644 --- a/tests/ui/mismatched_types/suggest-option-asderef-inference-var.stderr +++ b/tests/ui/mismatched_types/suggest-option-asderef-inference-var.stderr @@ -10,7 +10,7 @@ LL | let _has_inference_vars: Option<i32> = Some(0).map(deref_int); | required by a bound introduced by this call | = note: expected function signature `fn({integer}) -> _` - found function signature `for<'a> fn(&'a i32) -> _` + found function signature `fn(&i32) -> _` note: required by a bound in `Option::<T>::map` --> $SRC_DIR/core/src/option.rs:LL:COL help: consider wrapping the function in a closure diff --git a/tests/ui/mismatched_types/suggest-option-asderef-unfixable.stderr b/tests/ui/mismatched_types/suggest-option-asderef-unfixable.stderr index 1ac057a5f38..99c9028ae1e 100644 --- a/tests/ui/mismatched_types/suggest-option-asderef-unfixable.stderr +++ b/tests/ui/mismatched_types/suggest-option-asderef-unfixable.stderr @@ -10,7 +10,7 @@ LL | let _ = produces_string().and_then(takes_str_but_too_many_refs); | required by a bound introduced by this call | = note: expected function signature `fn(String) -> _` - found function signature `for<'a, 'b> fn(&'a &'b str) -> _` + found function signature `fn(&&str) -> _` note: required by a bound in `Option::<T>::and_then` --> $SRC_DIR/core/src/option.rs:LL:COL help: consider wrapping the function in a closure @@ -69,7 +69,7 @@ LL | let _ = Some(TypeWithoutDeref).and_then(takes_str_but_too_many_refs); | required by a bound introduced by this call | = note: expected function signature `fn(TypeWithoutDeref) -> _` - found function signature `for<'a, 'b> fn(&'a &'b str) -> _` + found function signature `fn(&&str) -> _` note: required by a bound in `Option::<T>::and_then` --> $SRC_DIR/core/src/option.rs:LL:COL help: consider wrapping the function in a closure diff --git a/tests/ui/mismatched_types/suggest-option-asderef.stderr b/tests/ui/mismatched_types/suggest-option-asderef.stderr index 1702a7f1dec..306c412e9d2 100644 --- a/tests/ui/mismatched_types/suggest-option-asderef.stderr +++ b/tests/ui/mismatched_types/suggest-option-asderef.stderr @@ -10,7 +10,7 @@ LL | let _: Option<()> = produces_string().and_then(takes_str); | required by a bound introduced by this call | = note: expected function signature `fn(String) -> _` - found function signature `for<'a> fn(&'a str) -> _` + found function signature `fn(&str) -> _` note: required by a bound in `Option::<T>::and_then` --> $SRC_DIR/core/src/option.rs:LL:COL help: consider wrapping the function in a closure @@ -34,7 +34,7 @@ LL | let _: Option<Option<()>> = produces_string().map(takes_str); | required by a bound introduced by this call | = note: expected function signature `fn(String) -> _` - found function signature `for<'a> fn(&'a str) -> _` + found function signature `fn(&str) -> _` note: required by a bound in `Option::<T>::map` --> $SRC_DIR/core/src/option.rs:LL:COL help: consider wrapping the function in a closure @@ -58,7 +58,7 @@ LL | let _: Option<Option<()>> = produces_string().map(takes_str_mut); | required by a bound introduced by this call | = note: expected function signature `fn(String) -> _` - found function signature `for<'a> fn(&'a mut str) -> _` + found function signature `fn(&mut str) -> _` note: required by a bound in `Option::<T>::map` --> $SRC_DIR/core/src/option.rs:LL:COL help: consider wrapping the function in a closure @@ -82,7 +82,7 @@ LL | let _ = produces_string().and_then(generic_ref); | required by a bound introduced by this call | = note: expected function signature `fn(String) -> _` - found function signature `for<'a> fn(&'a _) -> _` + found function signature `fn(&_) -> _` note: required by a bound in `Option::<T>::and_then` --> $SRC_DIR/core/src/option.rs:LL:COL help: consider wrapping the function in a closure diff --git a/tests/ui/nll/missing-universe-cause-issue-114907.rs b/tests/ui/nll/missing-universe-cause-issue-114907.rs index 9c69c6bdc36..a3eb5fceea9 100644 --- a/tests/ui/nll/missing-universe-cause-issue-114907.rs +++ b/tests/ui/nll/missing-universe-cause-issue-114907.rs @@ -31,8 +31,8 @@ fn accept<C: FnOnce(&())>(_: C) -> Handshake<HandshakeCallback<C>> { fn main() { let callback = |_| {}; accept(callback); - //~^ ERROR mismatched types - //~| ERROR mismatched types + //~^ ERROR implementation of `FnOnce` is not general enough + //~| ERROR implementation of `FnOnce` is not general enough //~| ERROR implementation of `FnOnce` is not general enough //~| ERROR implementation of `FnOnce` is not general enough //~| ERROR higher-ranked subtype error diff --git a/tests/ui/nll/missing-universe-cause-issue-114907.stderr b/tests/ui/nll/missing-universe-cause-issue-114907.stderr index a616d29c4fe..26ad1efec05 100644 --- a/tests/ui/nll/missing-universe-cause-issue-114907.stderr +++ b/tests/ui/nll/missing-universe-cause-issue-114907.stderr @@ -1,25 +1,11 @@ -error[E0308]: mismatched types +error: implementation of `FnOnce` is not general enough --> $DIR/missing-universe-cause-issue-114907.rs:33:5 | LL | accept(callback); - | ^^^^^^^^^^^^^^^^ one type is more general than the other - | - = note: expected trait `for<'a> FnOnce(&'a ())` - found trait `FnOnce(&())` -note: this closure does not fulfill the lifetime requirements - --> $DIR/missing-universe-cause-issue-114907.rs:32:20 - | -LL | let callback = |_| {}; - | ^^^ -note: the lifetime requirement is introduced here - --> $DIR/missing-universe-cause-issue-114907.rs:27:14 - | -LL | fn accept<C: FnOnce(&())>(_: C) -> Handshake<HandshakeCallback<C>> { - | ^^^^^^^^^^^ -help: consider specifying the type of the closure parameters + | ^^^^^^^^^^^^^^^^ implementation of `FnOnce` is not general enough | -LL | let callback = |_: &_| {}; - | ~~~~~~~ + = note: closure with signature `fn(&'2 ())` must implement `FnOnce<(&'1 (),)>`, for any lifetime `'1`... + = note: ...but it actually implements `FnOnce<(&'2 (),)>`, for some specific lifetime `'2` error: implementation of `FnOnce` is not general enough --> $DIR/missing-universe-cause-issue-114907.rs:33:5 @@ -29,6 +15,7 @@ LL | accept(callback); | = note: closure with signature `fn(&'2 ())` must implement `FnOnce<(&'1 (),)>`, for any lifetime `'1`... = note: ...but it actually implements `FnOnce<(&'2 (),)>`, for some specific lifetime `'2` + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error: implementation of `FnOnce` is not general enough --> $DIR/missing-universe-cause-issue-114907.rs:33:5 @@ -40,28 +27,15 @@ LL | accept(callback); = note: ...but it actually implements `FnOnce<(&'2 (),)>`, for some specific lifetime `'2` = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` -error[E0308]: mismatched types +error: implementation of `FnOnce` is not general enough --> $DIR/missing-universe-cause-issue-114907.rs:33:5 | LL | accept(callback); - | ^^^^^^^^^^^^^^^^ one type is more general than the other - | - = note: expected trait `for<'a> FnOnce(&'a ())` - found trait `FnOnce(&())` -note: this closure does not fulfill the lifetime requirements - --> $DIR/missing-universe-cause-issue-114907.rs:32:20 - | -LL | let callback = |_| {}; - | ^^^ -note: the lifetime requirement is introduced here - --> $DIR/missing-universe-cause-issue-114907.rs:20:21 - | -LL | struct Handshake<R: Role> { - | ^^^^ -help: consider specifying the type of the closure parameters + | ^^^^^^^^^^^^^^^^ implementation of `FnOnce` is not general enough | -LL | let callback = |_: &_| {}; - | ~~~~~~~ + = note: closure with signature `fn(&'2 ())` must implement `FnOnce<(&'1 (),)>`, for any lifetime `'1`... + = note: ...but it actually implements `FnOnce<(&'2 (),)>`, for some specific lifetime `'2` + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error: higher-ranked subtype error --> $DIR/missing-universe-cause-issue-114907.rs:33:21 @@ -79,4 +53,3 @@ LL | accept(callback); error: aborting due to 6 previous errors -For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/pattern/bindings-after-at/bind-by-move-neither-can-live-while-the-other-survives-1.stderr b/tests/ui/pattern/bindings-after-at/bind-by-move-neither-can-live-while-the-other-survives-1.stderr index 25838fbf0ab..16a93a0d47d 100644 --- a/tests/ui/pattern/bindings-after-at/bind-by-move-neither-can-live-while-the-other-survives-1.stderr +++ b/tests/ui/pattern/bindings-after-at/bind-by-move-neither-can-live-while-the-other-survives-1.stderr @@ -13,7 +13,7 @@ LL | Some(_z @ ref _y) => {} | ^^ ------ value borrowed here after move | | | value moved into `_z` here - | move occurs because `_z` has type `X` which does not implement the `Copy` trait + | move occurs because `_z` has type `X`, which does not implement the `Copy` trait | help: borrow this binding in the pattern to avoid moving the value | @@ -35,7 +35,7 @@ LL | Some(_z @ ref mut _y) => {} | ^^ ---------- value borrowed here after move | | | value moved into `_z` here - | move occurs because `_z` has type `X` which does not implement the `Copy` trait + | move occurs because `_z` has type `X`, which does not implement the `Copy` trait | help: borrow this binding in the pattern to avoid moving the value | diff --git a/tests/ui/pattern/bindings-after-at/borrowck-pat-by-move-and-ref-inverse-promotion.stderr b/tests/ui/pattern/bindings-after-at/borrowck-pat-by-move-and-ref-inverse-promotion.stderr index 815a4ade995..ea04d4bc055 100644 --- a/tests/ui/pattern/bindings-after-at/borrowck-pat-by-move-and-ref-inverse-promotion.stderr +++ b/tests/ui/pattern/bindings-after-at/borrowck-pat-by-move-and-ref-inverse-promotion.stderr @@ -5,7 +5,7 @@ LL | let a @ ref b = U; | ^ ----- value borrowed here after move | | | value moved into `a` here - | move occurs because `a` has type `U` which does not implement the `Copy` trait + | move occurs because `a` has type `U`, which does not implement the `Copy` trait | help: borrow this binding in the pattern to avoid moving the value | diff --git a/tests/ui/pattern/bindings-after-at/borrowck-pat-by-move-and-ref-inverse.stderr b/tests/ui/pattern/bindings-after-at/borrowck-pat-by-move-and-ref-inverse.stderr index fd7a51388bc..25c940a3200 100644 --- a/tests/ui/pattern/bindings-after-at/borrowck-pat-by-move-and-ref-inverse.stderr +++ b/tests/ui/pattern/bindings-after-at/borrowck-pat-by-move-and-ref-inverse.stderr @@ -5,7 +5,7 @@ LL | let a @ ref b = U; | ^ ----- value borrowed here after move | | | value moved into `a` here - | move occurs because `a` has type `U` which does not implement the `Copy` trait + | move occurs because `a` has type `U`, which does not implement the `Copy` trait | help: borrow this binding in the pattern to avoid moving the value | @@ -20,7 +20,7 @@ LL | let a @ (mut b @ ref mut c, d @ ref e) = (U, U); | | | | | value borrowed here after move | value moved into `a` here - | move occurs because `a` has type `(U, U)` which does not implement the `Copy` trait + | move occurs because `a` has type `(U, U)`, which does not implement the `Copy` trait | help: borrow this binding in the pattern to avoid moving the value | @@ -34,7 +34,7 @@ LL | let a @ (mut b @ ref mut c, d @ ref e) = (U, U); | ^^^^^ --------- value borrowed here after move | | | value moved into `b` here - | move occurs because `b` has type `U` which does not implement the `Copy` trait + | move occurs because `b` has type `U`, which does not implement the `Copy` trait | help: borrow this binding in the pattern to avoid moving the value | @@ -48,7 +48,7 @@ LL | let a @ (mut b @ ref mut c, d @ ref e) = (U, U); | ^ ----- value borrowed here after move | | | value moved into `d` here - | move occurs because `d` has type `U` which does not implement the `Copy` trait + | move occurs because `d` has type `U`, which does not implement the `Copy` trait | help: borrow this binding in the pattern to avoid moving the value | @@ -63,7 +63,7 @@ LL | let a @ [ref mut b, ref c] = [U, U]; | | | | | value borrowed here after move | value moved into `a` here - | move occurs because `a` has type `[U; 2]` which does not implement the `Copy` trait + | move occurs because `a` has type `[U; 2]`, which does not implement the `Copy` trait | help: borrow this binding in the pattern to avoid moving the value | @@ -77,7 +77,7 @@ LL | let a @ ref b = u(); | ^ ----- value borrowed here after move | | | value moved into `a` here - | move occurs because `a` has type `U` which does not implement the `Copy` trait + | move occurs because `a` has type `U`, which does not implement the `Copy` trait | help: borrow this binding in the pattern to avoid moving the value | @@ -92,7 +92,7 @@ LL | let a @ (mut b @ ref mut c, d @ ref e) = (u(), u()); | | | | | value borrowed here after move | value moved into `a` here - | move occurs because `a` has type `(U, U)` which does not implement the `Copy` trait + | move occurs because `a` has type `(U, U)`, which does not implement the `Copy` trait | help: borrow this binding in the pattern to avoid moving the value | @@ -106,7 +106,7 @@ LL | let a @ (mut b @ ref mut c, d @ ref e) = (u(), u()); | ^^^^^ --------- value borrowed here after move | | | value moved into `b` here - | move occurs because `b` has type `U` which does not implement the `Copy` trait + | move occurs because `b` has type `U`, which does not implement the `Copy` trait | help: borrow this binding in the pattern to avoid moving the value | @@ -120,7 +120,7 @@ LL | let a @ (mut b @ ref mut c, d @ ref e) = (u(), u()); | ^ ----- value borrowed here after move | | | value moved into `d` here - | move occurs because `d` has type `U` which does not implement the `Copy` trait + | move occurs because `d` has type `U`, which does not implement the `Copy` trait | help: borrow this binding in the pattern to avoid moving the value | @@ -135,7 +135,7 @@ LL | let a @ [ref mut b, ref c] = [u(), u()]; | | | | | value borrowed here after move | value moved into `a` here - | move occurs because `a` has type `[U; 2]` which does not implement the `Copy` trait + | move occurs because `a` has type `[U; 2]`, which does not implement the `Copy` trait | help: borrow this binding in the pattern to avoid moving the value | @@ -149,7 +149,7 @@ LL | a @ Some(ref b) => {} | ^ ----- value borrowed here after move | | | value moved into `a` here - | move occurs because `a` has type `Option<U>` which does not implement the `Copy` trait + | move occurs because `a` has type `Option<U>`, which does not implement the `Copy` trait | help: borrow this binding in the pattern to avoid moving the value | @@ -164,7 +164,7 @@ LL | a @ Some((mut b @ ref mut c, d @ ref e)) => {} | | | | | value borrowed here after move | value moved into `a` here - | move occurs because `a` has type `Option<(U, U)>` which does not implement the `Copy` trait + | move occurs because `a` has type `Option<(U, U)>`, which does not implement the `Copy` trait | help: borrow this binding in the pattern to avoid moving the value | @@ -178,7 +178,7 @@ LL | a @ Some((mut b @ ref mut c, d @ ref e)) => {} | ^^^^^ --------- value borrowed here after move | | | value moved into `b` here - | move occurs because `b` has type `U` which does not implement the `Copy` trait + | move occurs because `b` has type `U`, which does not implement the `Copy` trait | help: borrow this binding in the pattern to avoid moving the value | @@ -192,7 +192,7 @@ LL | a @ Some((mut b @ ref mut c, d @ ref e)) => {} | ^ ----- value borrowed here after move | | | value moved into `d` here - | move occurs because `d` has type `U` which does not implement the `Copy` trait + | move occurs because `d` has type `U`, which does not implement the `Copy` trait | help: borrow this binding in the pattern to avoid moving the value | @@ -207,7 +207,7 @@ LL | mut a @ Some([ref b, ref mut c]) => {} | | | | | value borrowed here after move | value moved into `a` here - | move occurs because `a` has type `Option<[U; 2]>` which does not implement the `Copy` trait + | move occurs because `a` has type `Option<[U; 2]>`, which does not implement the `Copy` trait | help: borrow this binding in the pattern to avoid moving the value | @@ -221,7 +221,7 @@ LL | a @ Some(ref b) => {} | ^ ----- value borrowed here after move | | | value moved into `a` here - | move occurs because `a` has type `Option<U>` which does not implement the `Copy` trait + | move occurs because `a` has type `Option<U>`, which does not implement the `Copy` trait | help: borrow this binding in the pattern to avoid moving the value | @@ -236,7 +236,7 @@ LL | a @ Some((mut b @ ref mut c, d @ ref e)) => {} | | | | | value borrowed here after move | value moved into `a` here - | move occurs because `a` has type `Option<(U, U)>` which does not implement the `Copy` trait + | move occurs because `a` has type `Option<(U, U)>`, which does not implement the `Copy` trait | help: borrow this binding in the pattern to avoid moving the value | @@ -250,7 +250,7 @@ LL | a @ Some((mut b @ ref mut c, d @ ref e)) => {} | ^^^^^ --------- value borrowed here after move | | | value moved into `b` here - | move occurs because `b` has type `U` which does not implement the `Copy` trait + | move occurs because `b` has type `U`, which does not implement the `Copy` trait | help: borrow this binding in the pattern to avoid moving the value | @@ -264,7 +264,7 @@ LL | a @ Some((mut b @ ref mut c, d @ ref e)) => {} | ^ ----- value borrowed here after move | | | value moved into `d` here - | move occurs because `d` has type `U` which does not implement the `Copy` trait + | move occurs because `d` has type `U`, which does not implement the `Copy` trait | help: borrow this binding in the pattern to avoid moving the value | @@ -279,7 +279,7 @@ LL | mut a @ Some([ref b, ref mut c]) => {} | | | | | value borrowed here after move | value moved into `a` here - | move occurs because `a` has type `Option<[U; 2]>` which does not implement the `Copy` trait + | move occurs because `a` has type `Option<[U; 2]>`, which does not implement the `Copy` trait | help: borrow this binding in the pattern to avoid moving the value | @@ -349,7 +349,7 @@ LL | fn f1(a @ ref b: U) {} | ^ ----- value borrowed here after move | | | value moved into `a` here - | move occurs because `a` has type `U` which does not implement the `Copy` trait + | move occurs because `a` has type `U`, which does not implement the `Copy` trait | help: borrow this binding in the pattern to avoid moving the value | @@ -364,7 +364,7 @@ LL | fn f2(mut a @ (b @ ref c, mut d @ ref e): (U, U)) {} | | | | | value borrowed here after move | value moved into `a` here - | move occurs because `a` has type `(U, U)` which does not implement the `Copy` trait + | move occurs because `a` has type `(U, U)`, which does not implement the `Copy` trait | help: borrow this binding in the pattern to avoid moving the value | @@ -378,7 +378,7 @@ LL | fn f2(mut a @ (b @ ref c, mut d @ ref e): (U, U)) {} | ^ ----- value borrowed here after move | | | value moved into `b` here - | move occurs because `b` has type `U` which does not implement the `Copy` trait + | move occurs because `b` has type `U`, which does not implement the `Copy` trait | help: borrow this binding in the pattern to avoid moving the value | @@ -392,7 +392,7 @@ LL | fn f2(mut a @ (b @ ref c, mut d @ ref e): (U, U)) {} | ^^^^^ ----- value borrowed here after move | | | value moved into `d` here - | move occurs because `d` has type `U` which does not implement the `Copy` trait + | move occurs because `d` has type `U`, which does not implement the `Copy` trait | help: borrow this binding in the pattern to avoid moving the value | @@ -417,7 +417,7 @@ LL | fn f3(a @ [ref mut b, ref c]: [U; 2]) {} | | | | | value borrowed here after move | value moved into `a` here - | move occurs because `a` has type `[U; 2]` which does not implement the `Copy` trait + | move occurs because `a` has type `[U; 2]`, which does not implement the `Copy` trait | help: borrow this binding in the pattern to avoid moving the value | diff --git a/tests/ui/pattern/bindings-after-at/borrowck-pat-ref-mut-twice.stderr b/tests/ui/pattern/bindings-after-at/borrowck-pat-ref-mut-twice.stderr index 3446148d2b1..76085f897ff 100644 --- a/tests/ui/pattern/bindings-after-at/borrowck-pat-ref-mut-twice.stderr +++ b/tests/ui/pattern/bindings-after-at/borrowck-pat-ref-mut-twice.stderr @@ -78,7 +78,7 @@ LL | let a @ (ref mut b, ref mut c) = (U, U); | | | | | value borrowed here after move | value moved into `a` here - | move occurs because `a` has type `(U, U)` which does not implement the `Copy` trait + | move occurs because `a` has type `(U, U)`, which does not implement the `Copy` trait | help: borrow this binding in the pattern to avoid moving the value | @@ -94,7 +94,7 @@ LL | let a @ (b, [c, d]) = &mut val; // Same as ^-- | | | value borrowed here after move | | value borrowed here after move | value moved into `a` here - | move occurs because `a` has type `&mut (U, [U; 2])` which does not implement the `Copy` trait + | move occurs because `a` has type `&mut (U, [U; 2])`, which does not implement the `Copy` trait | help: borrow this binding in the pattern to avoid moving the value | @@ -108,7 +108,7 @@ LL | let a @ &mut ref mut b = &mut U; | ^ --------- value borrowed here after move | | | value moved into `a` here - | move occurs because `a` has type `&mut U` which does not implement the `Copy` trait + | move occurs because `a` has type `&mut U`, which does not implement the `Copy` trait | help: borrow this binding in the pattern to avoid moving the value | @@ -123,7 +123,7 @@ LL | let a @ &mut (ref mut b, ref mut c) = &mut (U, U); | | | | | value borrowed here after move | value moved into `a` here - | move occurs because `a` has type `&mut (U, U)` which does not implement the `Copy` trait + | move occurs because `a` has type `&mut (U, U)`, which does not implement the `Copy` trait | help: borrow this binding in the pattern to avoid moving the value | diff --git a/tests/ui/pattern/bindings-after-at/default-binding-modes-both-sides-independent.stderr b/tests/ui/pattern/bindings-after-at/default-binding-modes-both-sides-independent.stderr index 36515c1a29b..a0a43e83a6a 100644 --- a/tests/ui/pattern/bindings-after-at/default-binding-modes-both-sides-independent.stderr +++ b/tests/ui/pattern/bindings-after-at/default-binding-modes-both-sides-independent.stderr @@ -29,7 +29,7 @@ LL | Ok(ref a @ b) | Err(b @ ref a) => { | ^ ----- value borrowed here after move | | | value moved into `b` here - | move occurs because `b` has type `NotCopy` which does not implement the `Copy` trait + | move occurs because `b` has type `NotCopy`, which does not implement the `Copy` trait | help: borrow this binding in the pattern to avoid moving the value | diff --git a/tests/ui/pattern/usefulness/integer-ranges/exhaustiveness.stderr b/tests/ui/pattern/usefulness/integer-ranges/exhaustiveness.stderr index 90d0fd7483a..68976c1b057 100644 --- a/tests/ui/pattern/usefulness/integer-ranges/exhaustiveness.stderr +++ b/tests/ui/pattern/usefulness/integer-ranges/exhaustiveness.stderr @@ -107,17 +107,17 @@ help: ensure that all possible cases are being handled by adding a match arm wit LL | match $s { $($t)+ => {}, u128::MAX => todo!() } | ++++++++++++++++++++++ -error[E0004]: non-exhaustive patterns: `5_u128..=u128::MAX` not covered +error[E0004]: non-exhaustive patterns: `5_u128..` not covered --> $DIR/exhaustiveness.rs:61:8 | LL | m!(0u128, 0..=4); - | ^^^^^ pattern `5_u128..=u128::MAX` not covered + | ^^^^^ pattern `5_u128..` not covered | = note: the matched value is of type `u128` help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown | -LL | match $s { $($t)+ => {}, 5_u128..=u128::MAX => todo!() } - | +++++++++++++++++++++++++++++++ +LL | match $s { $($t)+ => {}, 5_u128.. => todo!() } + | +++++++++++++++++++++ error[E0004]: non-exhaustive patterns: `0_u128` not covered --> $DIR/exhaustiveness.rs:62:8 diff --git a/tests/ui/resolve/issue-113808-invalid-unused-qualifications-suggestion.fixed b/tests/ui/resolve/issue-113808-invalid-unused-qualifications-suggestion.fixed index 8a67b20eec1..d95faef8ac4 100644 --- a/tests/ui/resolve/issue-113808-invalid-unused-qualifications-suggestion.fixed +++ b/tests/ui/resolve/issue-113808-invalid-unused-qualifications-suggestion.fixed @@ -18,6 +18,16 @@ impl Index<str> for A { } } +// This is used to make `use std::ops::Index;` not unused_import. +// details in fix(#122373) for issue #121331 +pub struct C; +impl Index<str> for C { + type Output = (); + fn index(&self, _: str) -> &Self::Output { + &() + } +} + mod inner { pub trait Trait<T> {} } @@ -29,4 +39,5 @@ use inner::Trait; impl Trait<u8> for () {} //~^ ERROR unnecessary qualification +impl Trait<A> for A {} fn main() {} diff --git a/tests/ui/resolve/issue-113808-invalid-unused-qualifications-suggestion.rs b/tests/ui/resolve/issue-113808-invalid-unused-qualifications-suggestion.rs index 528edb331cf..0eee8f71ad4 100644 --- a/tests/ui/resolve/issue-113808-invalid-unused-qualifications-suggestion.rs +++ b/tests/ui/resolve/issue-113808-invalid-unused-qualifications-suggestion.rs @@ -18,6 +18,16 @@ impl ops::Index<str> for A { } } +// This is used to make `use std::ops::Index;` not unused_import. +// details in fix(#122373) for issue #121331 +pub struct C; +impl Index<str> for C { + type Output = (); + fn index(&self, _: str) -> &Self::Output { + &() + } +} + mod inner { pub trait Trait<T> {} } @@ -29,4 +39,5 @@ use inner::Trait; impl inner::Trait<u8> for () {} //~^ ERROR unnecessary qualification +impl Trait<A> for A {} fn main() {} diff --git a/tests/ui/resolve/issue-113808-invalid-unused-qualifications-suggestion.stderr b/tests/ui/resolve/issue-113808-invalid-unused-qualifications-suggestion.stderr index bcda7210712..e105b754b71 100644 --- a/tests/ui/resolve/issue-113808-invalid-unused-qualifications-suggestion.stderr +++ b/tests/ui/resolve/issue-113808-invalid-unused-qualifications-suggestion.stderr @@ -16,7 +16,7 @@ LL + impl Index<str> for A { | error: unnecessary qualification - --> $DIR/issue-113808-invalid-unused-qualifications-suggestion.rs:29:6 + --> $DIR/issue-113808-invalid-unused-qualifications-suggestion.rs:39:6 | LL | impl inner::Trait<u8> for () {} | ^^^^^^^^^^^^^^^^ diff --git a/tests/ui/resolve/unused-qualifications-suggestion.fixed b/tests/ui/resolve/unused-qualifications-suggestion.fixed index 6935f611b36..22e0daea467 100644 --- a/tests/ui/resolve/unused-qualifications-suggestion.fixed +++ b/tests/ui/resolve/unused-qualifications-suggestion.fixed @@ -16,8 +16,10 @@ fn main() { use foo::bar; bar(); //~^ ERROR unnecessary qualification + bar(); use baz::qux::quux; quux(); //~^ ERROR unnecessary qualification + quux(); } diff --git a/tests/ui/resolve/unused-qualifications-suggestion.rs b/tests/ui/resolve/unused-qualifications-suggestion.rs index b3fe04ff0ea..89516c1344a 100644 --- a/tests/ui/resolve/unused-qualifications-suggestion.rs +++ b/tests/ui/resolve/unused-qualifications-suggestion.rs @@ -16,8 +16,10 @@ fn main() { use foo::bar; foo::bar(); //~^ ERROR unnecessary qualification + bar(); use baz::qux::quux; baz::qux::quux(); //~^ ERROR unnecessary qualification + quux(); } diff --git a/tests/ui/resolve/unused-qualifications-suggestion.stderr b/tests/ui/resolve/unused-qualifications-suggestion.stderr index e3dac37fc6e..5b71ba9e222 100644 --- a/tests/ui/resolve/unused-qualifications-suggestion.stderr +++ b/tests/ui/resolve/unused-qualifications-suggestion.stderr @@ -16,7 +16,7 @@ LL + bar(); | error: unnecessary qualification - --> $DIR/unused-qualifications-suggestion.rs:21:5 + --> $DIR/unused-qualifications-suggestion.rs:22:5 | LL | baz::qux::quux(); | ^^^^^^^^^^^^^^ diff --git a/tests/ui/rfcs/rfc-1623-static/rfc1623-2.rs b/tests/ui/rfcs/rfc-1623-static/rfc1623-2.rs index c0e13a5f5f0..5d11941414f 100644 --- a/tests/ui/rfcs/rfc-1623-static/rfc1623-2.rs +++ b/tests/ui/rfcs/rfc-1623-static/rfc1623-2.rs @@ -26,8 +26,8 @@ static SOME_STRUCT: &SomeStruct = &SomeStruct { foo: &Foo { bools: &[false, true] }, bar: &Bar { bools: &[true, true] }, f: &id, - //~^ ERROR mismatched types - //~| ERROR mismatched types + //~^ ERROR implementation of `Fn` is not general enough + //~| ERROR implementation of `Fn` is not general enough //~| ERROR implementation of `FnOnce` is not general enough //~| ERROR implementation of `FnOnce` is not general enough }; diff --git a/tests/ui/rfcs/rfc-1623-static/rfc1623-2.stderr b/tests/ui/rfcs/rfc-1623-static/rfc1623-2.stderr index 52c700c326e..5c98a9d4fb4 100644 --- a/tests/ui/rfcs/rfc-1623-static/rfc1623-2.stderr +++ b/tests/ui/rfcs/rfc-1623-static/rfc1623-2.stderr @@ -1,21 +1,20 @@ -error[E0308]: mismatched types +error: implementation of `Fn` is not general enough --> $DIR/rfc1623-2.rs:28:8 | LL | f: &id, - | ^^^ one type is more general than the other + | ^^^ implementation of `Fn` is not general enough | - = note: expected trait `for<'a, 'b> Fn(&'a Foo<'b>)` - found trait `Fn(&Foo<'_>)` + = note: `fn(&'2 Foo<'_>) -> &'2 Foo<'_> {id::<&'2 Foo<'_>>}` must implement `Fn<(&'1 Foo<'b>,)>`, for any lifetime `'1`... + = note: ...but it actually implements `Fn<(&'2 Foo<'_>,)>`, for some specific lifetime `'2` -error[E0308]: mismatched types +error: implementation of `Fn` is not general enough --> $DIR/rfc1623-2.rs:28:8 | LL | f: &id, - | ^^^ one type is more general than the other + | ^^^ implementation of `Fn` is not general enough | - = note: expected trait `for<'a, 'b> Fn(&'a Foo<'b>)` - found trait `Fn(&Foo<'_>)` - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + = note: `fn(&Foo<'2>) -> &Foo<'2> {id::<&Foo<'2>>}` must implement `Fn<(&'a Foo<'1>,)>`, for any lifetime `'1`... + = note: ...but it actually implements `Fn<(&Foo<'2>,)>`, for some specific lifetime `'2` error: implementation of `FnOnce` is not general enough --> $DIR/rfc1623-2.rs:28:8 @@ -37,4 +36,3 @@ LL | f: &id, error: aborting due to 4 previous errors -For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/simd/const-err-trumps-simd-err.rs b/tests/ui/simd/const-err-trumps-simd-err.rs new file mode 100644 index 00000000000..06a747273ab --- /dev/null +++ b/tests/ui/simd/const-err-trumps-simd-err.rs @@ -0,0 +1,24 @@ +//@build-fail +//! Make sure that monomorphization-time const errors from `static_assert` take priority over the +//! error from simd_extract. Basically this checks that if a const fails to evaluate in some +//! function, we don't bother codegen'ing the function. +#![feature(generic_arg_infer)] +#![feature(core_intrinsics)] +#![feature(repr_simd)] +#![feature(inline_const)] +use std::intrinsics::simd::*; + +#[repr(simd)] +#[allow(non_camel_case_types)] +struct int8x4_t(u8,u8,u8,u8); + +fn get_elem<const LANE: u32>(a: int8x4_t) -> u8 { + const { assert!(LANE < 4); } // the error should be here... + //~^ ERROR failed + //~| assertion failed + unsafe { simd_extract(a, LANE) } // ...not here +} + +fn main() { + get_elem::<4>(int8x4_t(0,0,0,0)); +} diff --git a/tests/ui/simd/const-err-trumps-simd-err.stderr b/tests/ui/simd/const-err-trumps-simd-err.stderr new file mode 100644 index 00000000000..1e46667cf4e --- /dev/null +++ b/tests/ui/simd/const-err-trumps-simd-err.stderr @@ -0,0 +1,23 @@ +error[E0080]: evaluation of `get_elem::<4>::{constant#0}` failed + --> $DIR/const-err-trumps-simd-err.rs:16:13 + | +LL | const { assert!(LANE < 4); } // the error should be here... + | ^^^^^^^^^^^^^^^^^ the evaluated program panicked at 'assertion failed: LANE < 4', $DIR/const-err-trumps-simd-err.rs:16:13 + | + = note: this error originates in the macro `assert` (in Nightly builds, run with -Z macro-backtrace for more info) + +note: erroneous constant encountered + --> $DIR/const-err-trumps-simd-err.rs:16:5 + | +LL | const { assert!(LANE < 4); } // the error should be here... + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +note: the above error was encountered while instantiating `fn get_elem::<4>` + --> $DIR/const-err-trumps-simd-err.rs:23:5 + | +LL | get_elem::<4>(int8x4_t(0,0,0,0)); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0080`. diff --git a/tests/ui/stats/hir-stats.stderr b/tests/ui/stats/hir-stats.stderr index 579a5d5180e..dc24833c267 100644 --- a/tests/ui/stats/hir-stats.stderr +++ b/tests/ui/stats/hir-stats.stderr @@ -17,7 +17,7 @@ ast-stats-1 - Fn 96 ( 1.4%) 1 ast-stats-1 FnDecl 120 ( 1.8%) 5 24 ast-stats-1 FieldDef 160 ( 2.4%) 2 80 ast-stats-1 Stmt 160 ( 2.4%) 5 32 -ast-stats-1 - Local 32 ( 0.5%) 1 +ast-stats-1 - Let 32 ( 0.5%) 1 ast-stats-1 - MacCall 32 ( 0.5%) 1 ast-stats-1 - Expr 96 ( 1.4%) 3 ast-stats-1 Param 160 ( 2.4%) 4 40 @@ -75,7 +75,7 @@ ast-stats-2 - DocComment 32 ( 0.4%) 1 ast-stats-2 - Normal 96 ( 1.3%) 3 ast-stats-2 FieldDef 160 ( 2.2%) 2 80 ast-stats-2 Stmt 160 ( 2.2%) 5 32 -ast-stats-2 - Local 32 ( 0.4%) 1 +ast-stats-2 - Let 32 ( 0.4%) 1 ast-stats-2 - Semi 32 ( 0.4%) 1 ast-stats-2 - Expr 96 ( 1.3%) 3 ast-stats-2 Param 160 ( 2.2%) 4 40 @@ -131,7 +131,7 @@ hir-stats ImplItemRef 72 ( 0.8%) 2 36 hir-stats Arm 80 ( 0.9%) 2 40 hir-stats FieldDef 96 ( 1.1%) 2 48 hir-stats Stmt 96 ( 1.1%) 3 32 -hir-stats - Local 32 ( 0.4%) 1 +hir-stats - Let 32 ( 0.4%) 1 hir-stats - Semi 32 ( 0.4%) 1 hir-stats - Expr 32 ( 0.4%) 1 hir-stats FnDecl 120 ( 1.3%) 3 40 diff --git a/tests/ui/suggestions/clone-bounds-121524.rs b/tests/ui/suggestions/clone-bounds-121524.rs new file mode 100644 index 00000000000..8cd60b452de --- /dev/null +++ b/tests/ui/suggestions/clone-bounds-121524.rs @@ -0,0 +1,19 @@ +#[derive(Clone)] +struct ThingThatDoesAThing; + +trait DoesAThing {} + +impl DoesAThing for ThingThatDoesAThing {} + +fn clones_impl_ref_inline(thing: &impl DoesAThing) { + //~^ HELP consider further restricting this bound + drops_impl_owned(thing.clone()); //~ ERROR E0277 + //~^ NOTE copies the reference + //~| NOTE the trait `DoesAThing` is not implemented for `&impl DoesAThing` +} + +fn drops_impl_owned(_thing: impl DoesAThing) { } + +fn main() { + clones_impl_ref_inline(&ThingThatDoesAThing); +} diff --git a/tests/ui/suggestions/clone-bounds-121524.stderr b/tests/ui/suggestions/clone-bounds-121524.stderr new file mode 100644 index 00000000000..6d60508a4a1 --- /dev/null +++ b/tests/ui/suggestions/clone-bounds-121524.stderr @@ -0,0 +1,19 @@ +error[E0277]: the trait bound `&impl DoesAThing: DoesAThing` is not satisfied + --> $DIR/clone-bounds-121524.rs:10:22 + | +LL | drops_impl_owned(thing.clone()); + | ^^^^^^^^^^^^^ the trait `DoesAThing` is not implemented for `&impl DoesAThing` + | +note: this `clone()` copies the reference, which does not do anything, because `impl DoesAThing` does not implement `Clone` + --> $DIR/clone-bounds-121524.rs:10:28 + | +LL | drops_impl_owned(thing.clone()); + | ^^^^^ +help: consider further restricting this bound + | +LL | fn clones_impl_ref_inline(thing: &impl DoesAThing + Clone) { + | +++++++ + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/suggestions/late-bound-in-borrow-closure-sugg.stderr b/tests/ui/suggestions/late-bound-in-borrow-closure-sugg.stderr index ee924522564..f0acf1dbb96 100644 --- a/tests/ui/suggestions/late-bound-in-borrow-closure-sugg.stderr +++ b/tests/ui/suggestions/late-bound-in-borrow-closure-sugg.stderr @@ -10,7 +10,7 @@ LL | trader.set_closure(closure); | required by a bound introduced by this call | = note: expected closure signature `for<'a, 'b> fn(&'a mut Trader<'b>) -> _` - found closure signature `for<'a> fn(Trader<'a>) -> _` + found closure signature `fn(Trader<'_>) -> _` note: required by a bound in `Trader::<'a>::set_closure` --> $DIR/late-bound-in-borrow-closure-sugg.rs:15:50 | diff --git a/tests/ui/suggestions/ref-pattern-binding.stderr b/tests/ui/suggestions/ref-pattern-binding.stderr index 69ce5d440af..af21c6aef70 100644 --- a/tests/ui/suggestions/ref-pattern-binding.stderr +++ b/tests/ui/suggestions/ref-pattern-binding.stderr @@ -5,7 +5,7 @@ LL | let _moved @ ref _from = String::from("foo"); | ^^^^^^ --------- value borrowed here after move | | | value moved into `_moved` here - | move occurs because `_moved` has type `String` which does not implement the `Copy` trait + | move occurs because `_moved` has type `String`, which does not implement the `Copy` trait | help: borrow this binding in the pattern to avoid moving the value | @@ -35,7 +35,7 @@ LL | let _moved @ S { ref f } = S { f: String::from("foo") }; | ^^^^^^ ----- value borrowed here after move | | | value moved into `_moved` here - | move occurs because `_moved` has type `S` which does not implement the `Copy` trait + | move occurs because `_moved` has type `S`, which does not implement the `Copy` trait | help: borrow this binding in the pattern to avoid moving the value | diff --git a/tests/ui/traits/non_lifetime_binders/type-match-with-late-bound.stderr b/tests/ui/traits/non_lifetime_binders/type-match-with-late-bound.stderr index 6c259621466..40e16dde6e4 100644 --- a/tests/ui/traits/non_lifetime_binders/type-match-with-late-bound.stderr +++ b/tests/ui/traits/non_lifetime_binders/type-match-with-late-bound.stderr @@ -8,6 +8,27 @@ LL | #![feature(non_lifetime_binders)] = note: `#[warn(incomplete_features)]` on by default error[E0309]: the placeholder type `!1_"F"` may not live long enough + --> $DIR/type-match-with-late-bound.rs:8:1 + | +LL | async fn walk2<'a, T: 'a>(_: T) + | ^ -- the placeholder type `!1_"F"` must be valid for the lifetime `'a` as defined here... + | _| + | | +LL | | where +LL | | for<F> F: 'a, + | |_________________^ ...so that the type `F` will meet its required lifetime bounds... + | +note: ...that is required by this bound + --> $DIR/type-match-with-late-bound.rs:10:15 + | +LL | for<F> F: 'a, + | ^^ +help: consider adding an explicit lifetime bound + | +LL | for<F> F: 'a, !1_"F": 'a + | ~~~~~~~~~~~~ + +error[E0309]: the placeholder type `!1_"F"` may not live long enough --> $DIR/type-match-with-late-bound.rs:11:1 | LL | async fn walk2<'a, T: 'a>(_: T) @@ -35,6 +56,6 @@ help: consider adding an explicit lifetime bound LL | for<F> F: 'a, !2_"F": 'a | ~~~~~~~~~~~~ -error: aborting due to 2 previous errors; 1 warning emitted +error: aborting due to 3 previous errors; 1 warning emitted For more information about this error, try `rustc --explain E0309`. diff --git a/tests/ui/traits/trait-upcasting/higher-ranked-upcasting-ok.current.stderr b/tests/ui/traits/trait-upcasting/higher-ranked-upcasting-ok.current.stderr new file mode 100644 index 00000000000..098ab71e946 --- /dev/null +++ b/tests/ui/traits/trait-upcasting/higher-ranked-upcasting-ok.current.stderr @@ -0,0 +1,22 @@ +error[E0308]: mismatched types + --> $DIR/higher-ranked-upcasting-ok.rs:17:5 + | +LL | x + | ^ one type is more general than the other + | + = note: expected existential trait ref `for<'a, 'b> Supertrait<'a, 'b>` + found existential trait ref `for<'a> Supertrait<'a, 'a>` + +error[E0308]: mismatched types + --> $DIR/higher-ranked-upcasting-ok.rs:17:5 + | +LL | x + | ^ one type is more general than the other + | + = note: expected existential trait ref `for<'a, 'b> Supertrait<'a, 'b>` + found existential trait ref `for<'a> Supertrait<'a, 'a>` + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/traits/trait-upcasting/higher-ranked-upcasting-ok.next.stderr b/tests/ui/traits/trait-upcasting/higher-ranked-upcasting-ok.next.stderr new file mode 100644 index 00000000000..ac516fd6975 --- /dev/null +++ b/tests/ui/traits/trait-upcasting/higher-ranked-upcasting-ok.next.stderr @@ -0,0 +1,14 @@ +error[E0308]: mismatched types + --> $DIR/higher-ranked-upcasting-ok.rs:17:5 + | +LL | fn ok(x: &dyn for<'a, 'b> Subtrait<'a, 'b>) -> &dyn for<'a> Supertrait<'a, 'a> { + | ------------------------------- expected `&dyn for<'a> Supertrait<'a, 'a>` because of return type +LL | x + | ^ expected trait `Supertrait`, found trait `Subtrait` + | + = note: expected reference `&dyn for<'a> Supertrait<'a, 'a>` + found reference `&dyn for<'a, 'b> Subtrait<'a, 'b>` + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/traits/trait-upcasting/higher-ranked-upcasting-ok.rs b/tests/ui/traits/trait-upcasting/higher-ranked-upcasting-ok.rs new file mode 100644 index 00000000000..00743203179 --- /dev/null +++ b/tests/ui/traits/trait-upcasting/higher-ranked-upcasting-ok.rs @@ -0,0 +1,19 @@ +//@ revisions: current next +//@ ignore-compare-mode-next-solver (explicit revisions) +//@[next] compile-flags: -Znext-solver + +// We should be able to instantiate a binder during trait upcasting. +// This test could be `check-pass`, but we should make sure that we +// do so in both trait solvers. +#![feature(trait_upcasting)] +#![crate_type = "rlib"] +trait Supertrait<'a, 'b> {} + +trait Subtrait<'a, 'b>: Supertrait<'a, 'b> {} + +impl<'a> Supertrait<'a, 'a> for () {} +impl<'a> Subtrait<'a, 'a> for () {} +fn ok(x: &dyn for<'a, 'b> Subtrait<'a, 'b>) -> &dyn for<'a> Supertrait<'a, 'a> { + x //~ ERROR mismatched types + //[current]~^ ERROR mismatched types +} diff --git a/tests/ui/traits/trait-upcasting/higher-ranked-upcasting-ub.current.stderr b/tests/ui/traits/trait-upcasting/higher-ranked-upcasting-ub.current.stderr new file mode 100644 index 00000000000..bac82983268 --- /dev/null +++ b/tests/ui/traits/trait-upcasting/higher-ranked-upcasting-ub.current.stderr @@ -0,0 +1,22 @@ +error[E0308]: mismatched types + --> $DIR/higher-ranked-upcasting-ub.rs:22:5 + | +LL | x + | ^ one type is more general than the other + | + = note: expected existential trait ref `for<'a> Supertrait<'a, 'a>` + found existential trait ref `for<'a, 'b> Supertrait<'a, 'b>` + +error[E0308]: mismatched types + --> $DIR/higher-ranked-upcasting-ub.rs:22:5 + | +LL | x + | ^ one type is more general than the other + | + = note: expected existential trait ref `for<'a> Supertrait<'a, 'a>` + found existential trait ref `for<'a, 'b> Supertrait<'a, 'b>` + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/traits/trait-upcasting/higher-ranked-upcasting-ub.next.stderr b/tests/ui/traits/trait-upcasting/higher-ranked-upcasting-ub.next.stderr new file mode 100644 index 00000000000..b82f1eef42b --- /dev/null +++ b/tests/ui/traits/trait-upcasting/higher-ranked-upcasting-ub.next.stderr @@ -0,0 +1,14 @@ +error[E0308]: mismatched types + --> $DIR/higher-ranked-upcasting-ub.rs:22:5 + | +LL | fn unsound(x: &dyn for<'a> Subtrait<'a, 'a>) -> &dyn for<'a, 'b> Supertrait<'a, 'b> { + | ----------------------------------- expected `&dyn for<'a, 'b> Supertrait<'a, 'b>` because of return type +LL | x + | ^ expected trait `Supertrait`, found trait `Subtrait` + | + = note: expected reference `&dyn for<'a, 'b> Supertrait<'a, 'b>` + found reference `&dyn for<'a> Subtrait<'a, 'a>` + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/traits/trait-upcasting/higher-ranked-upcasting-ub.rs b/tests/ui/traits/trait-upcasting/higher-ranked-upcasting-ub.rs new file mode 100644 index 00000000000..2cf6fc75e77 --- /dev/null +++ b/tests/ui/traits/trait-upcasting/higher-ranked-upcasting-ub.rs @@ -0,0 +1,37 @@ +//@ revisions: current next +//@ ignore-compare-mode-next-solver (explicit revisions) +//@[next] compile-flags: -Znext-solver + +// We previously wrongly instantiated binders during trait upcasting, +// allowing the super trait to be more generic than the sub trait. +// This was unsound. +#![feature(trait_upcasting)] +trait Supertrait<'a, 'b> { + fn cast(&self, x: &'a str) -> &'b str; +} + +trait Subtrait<'a, 'b>: Supertrait<'a, 'b> {} + +impl<'a> Supertrait<'a, 'a> for () { + fn cast(&self, x: &'a str) -> &'a str { + x + } +} +impl<'a> Subtrait<'a, 'a> for () {} +fn unsound(x: &dyn for<'a> Subtrait<'a, 'a>) -> &dyn for<'a, 'b> Supertrait<'a, 'b> { + x //~ ERROR mismatched types + //[current]~^ ERROR mismatched types +} + +fn transmute<'a, 'b>(x: &'a str) -> &'b str { + unsound(&()).cast(x) +} + +fn main() { + let x; + { + let mut temp = String::from("hello there"); + x = transmute(temp.as_str()); + } + println!("{x}"); +} diff --git a/tests/ui/transmutability/alignment/align-fail.stderr b/tests/ui/transmutability/alignment/align-fail.stderr index c92c3d841f2..f05e55fb024 100644 --- a/tests/ui/transmutability/alignment/align-fail.stderr +++ b/tests/ui/transmutability/alignment/align-fail.stderr @@ -2,7 +2,7 @@ error[E0277]: `&[u8; 0]` cannot be safely transmuted into `&[u16; 0]` --> $DIR/align-fail.rs:21:55 | LL | ...tatic [u8; 0], &'static [u16; 0]>(); - | ^^^^^^^^^^^^^^^^^ The minimum alignment of `&[u8; 0]` (1) should be greater than that of `&[u16; 0]` (2) + | ^^^^^^^^^^^^^^^^^ the minimum alignment of `&[u8; 0]` (1) should be greater than that of `&[u16; 0]` (2) | note: required by a bound in `is_maybe_transmutable` --> $DIR/align-fail.rs:9:14 diff --git a/tests/ui/transmutability/arrays/should_require_well_defined_layout.stderr b/tests/ui/transmutability/arrays/should_require_well_defined_layout.stderr index fd21ac34183..e486928a445 100644 --- a/tests/ui/transmutability/arrays/should_require_well_defined_layout.stderr +++ b/tests/ui/transmutability/arrays/should_require_well_defined_layout.stderr @@ -2,7 +2,7 @@ error[E0277]: `[String; 0]` cannot be safely transmuted into `()` --> $DIR/should_require_well_defined_layout.rs:25:52 | LL | assert::is_maybe_transmutable::<repr_rust, ()>(); - | ^^ `[String; 0]` does not have a well-specified layout + | ^^ analyzing the transmutability of `[String; 0]` is not yet supported. | note: required by a bound in `is_maybe_transmutable` --> $DIR/should_require_well_defined_layout.rs:12:14 @@ -23,7 +23,7 @@ error[E0277]: `u128` cannot be safely transmuted into `[String; 0]` --> $DIR/should_require_well_defined_layout.rs:26:47 | LL | assert::is_maybe_transmutable::<u128, repr_rust>(); - | ^^^^^^^^^ `[String; 0]` does not have a well-specified layout + | ^^^^^^^^^ analyzing the transmutability of `[String; 0]` is not yet supported. | note: required by a bound in `is_maybe_transmutable` --> $DIR/should_require_well_defined_layout.rs:12:14 @@ -44,7 +44,7 @@ error[E0277]: `[String; 1]` cannot be safely transmuted into `()` --> $DIR/should_require_well_defined_layout.rs:31:52 | LL | assert::is_maybe_transmutable::<repr_rust, ()>(); - | ^^ `[String; 1]` does not have a well-specified layout + | ^^ analyzing the transmutability of `[String; 1]` is not yet supported. | note: required by a bound in `is_maybe_transmutable` --> $DIR/should_require_well_defined_layout.rs:12:14 @@ -65,7 +65,7 @@ error[E0277]: `u128` cannot be safely transmuted into `[String; 1]` --> $DIR/should_require_well_defined_layout.rs:32:47 | LL | assert::is_maybe_transmutable::<u128, repr_rust>(); - | ^^^^^^^^^ `[String; 1]` does not have a well-specified layout + | ^^^^^^^^^ analyzing the transmutability of `[String; 1]` is not yet supported. | note: required by a bound in `is_maybe_transmutable` --> $DIR/should_require_well_defined_layout.rs:12:14 @@ -86,7 +86,7 @@ error[E0277]: `[String; 2]` cannot be safely transmuted into `()` --> $DIR/should_require_well_defined_layout.rs:37:52 | LL | assert::is_maybe_transmutable::<repr_rust, ()>(); - | ^^ `[String; 2]` does not have a well-specified layout + | ^^ analyzing the transmutability of `[String; 2]` is not yet supported. | note: required by a bound in `is_maybe_transmutable` --> $DIR/should_require_well_defined_layout.rs:12:14 @@ -107,7 +107,7 @@ error[E0277]: `u128` cannot be safely transmuted into `[String; 2]` --> $DIR/should_require_well_defined_layout.rs:38:47 | LL | assert::is_maybe_transmutable::<u128, repr_rust>(); - | ^^^^^^^^^ `[String; 2]` does not have a well-specified layout + | ^^^^^^^^^ analyzing the transmutability of `[String; 2]` is not yet supported. | note: required by a bound in `is_maybe_transmutable` --> $DIR/should_require_well_defined_layout.rs:12:14 diff --git a/tests/ui/transmutability/enums/repr/primitive_reprs_should_have_correct_length.stderr b/tests/ui/transmutability/enums/repr/primitive_reprs_should_have_correct_length.stderr index b2ff04eeed9..6c88bf4ff96 100644 --- a/tests/ui/transmutability/enums/repr/primitive_reprs_should_have_correct_length.stderr +++ b/tests/ui/transmutability/enums/repr/primitive_reprs_should_have_correct_length.stderr @@ -2,7 +2,7 @@ error[E0277]: `Zst` cannot be safely transmuted into `V0i8` --> $DIR/primitive_reprs_should_have_correct_length.rs:46:44 | LL | assert::is_transmutable::<Smaller, Current>(); - | ^^^^^^^ The size of `Zst` is smaller than the size of `V0i8` + | ^^^^^^^ the size of `Zst` is smaller than the size of `V0i8` | note: required by a bound in `is_transmutable` --> $DIR/primitive_reprs_should_have_correct_length.rs:12:14 @@ -24,7 +24,7 @@ error[E0277]: `V0i8` cannot be safely transmuted into `u16` --> $DIR/primitive_reprs_should_have_correct_length.rs:48:44 | LL | assert::is_transmutable::<Current, Larger>(); - | ^^^^^^ The size of `V0i8` is smaller than the size of `u16` + | ^^^^^^ the size of `V0i8` is smaller than the size of `u16` | note: required by a bound in `is_transmutable` --> $DIR/primitive_reprs_should_have_correct_length.rs:12:14 @@ -46,7 +46,7 @@ error[E0277]: `Zst` cannot be safely transmuted into `V0u8` --> $DIR/primitive_reprs_should_have_correct_length.rs:54:44 | LL | assert::is_transmutable::<Smaller, Current>(); - | ^^^^^^^ The size of `Zst` is smaller than the size of `V0u8` + | ^^^^^^^ the size of `Zst` is smaller than the size of `V0u8` | note: required by a bound in `is_transmutable` --> $DIR/primitive_reprs_should_have_correct_length.rs:12:14 @@ -68,7 +68,7 @@ error[E0277]: `V0u8` cannot be safely transmuted into `u16` --> $DIR/primitive_reprs_should_have_correct_length.rs:56:44 | LL | assert::is_transmutable::<Current, Larger>(); - | ^^^^^^ The size of `V0u8` is smaller than the size of `u16` + | ^^^^^^ the size of `V0u8` is smaller than the size of `u16` | note: required by a bound in `is_transmutable` --> $DIR/primitive_reprs_should_have_correct_length.rs:12:14 @@ -90,7 +90,7 @@ error[E0277]: `u8` cannot be safely transmuted into `V0i16` --> $DIR/primitive_reprs_should_have_correct_length.rs:68:44 | LL | assert::is_transmutable::<Smaller, Current>(); - | ^^^^^^^ The size of `u8` is smaller than the size of `V0i16` + | ^^^^^^^ the size of `u8` is smaller than the size of `V0i16` | note: required by a bound in `is_transmutable` --> $DIR/primitive_reprs_should_have_correct_length.rs:12:14 @@ -112,7 +112,7 @@ error[E0277]: `V0i16` cannot be safely transmuted into `u32` --> $DIR/primitive_reprs_should_have_correct_length.rs:70:44 | LL | assert::is_transmutable::<Current, Larger>(); - | ^^^^^^ The size of `V0i16` is smaller than the size of `u32` + | ^^^^^^ the size of `V0i16` is smaller than the size of `u32` | note: required by a bound in `is_transmutable` --> $DIR/primitive_reprs_should_have_correct_length.rs:12:14 @@ -134,7 +134,7 @@ error[E0277]: `u8` cannot be safely transmuted into `V0u16` --> $DIR/primitive_reprs_should_have_correct_length.rs:76:44 | LL | assert::is_transmutable::<Smaller, Current>(); - | ^^^^^^^ The size of `u8` is smaller than the size of `V0u16` + | ^^^^^^^ the size of `u8` is smaller than the size of `V0u16` | note: required by a bound in `is_transmutable` --> $DIR/primitive_reprs_should_have_correct_length.rs:12:14 @@ -156,7 +156,7 @@ error[E0277]: `V0u16` cannot be safely transmuted into `u32` --> $DIR/primitive_reprs_should_have_correct_length.rs:78:44 | LL | assert::is_transmutable::<Current, Larger>(); - | ^^^^^^ The size of `V0u16` is smaller than the size of `u32` + | ^^^^^^ the size of `V0u16` is smaller than the size of `u32` | note: required by a bound in `is_transmutable` --> $DIR/primitive_reprs_should_have_correct_length.rs:12:14 @@ -178,7 +178,7 @@ error[E0277]: `u16` cannot be safely transmuted into `V0i32` --> $DIR/primitive_reprs_should_have_correct_length.rs:90:44 | LL | assert::is_transmutable::<Smaller, Current>(); - | ^^^^^^^ The size of `u16` is smaller than the size of `V0i32` + | ^^^^^^^ the size of `u16` is smaller than the size of `V0i32` | note: required by a bound in `is_transmutable` --> $DIR/primitive_reprs_should_have_correct_length.rs:12:14 @@ -200,7 +200,7 @@ error[E0277]: `V0i32` cannot be safely transmuted into `u64` --> $DIR/primitive_reprs_should_have_correct_length.rs:92:44 | LL | assert::is_transmutable::<Current, Larger>(); - | ^^^^^^ The size of `V0i32` is smaller than the size of `u64` + | ^^^^^^ the size of `V0i32` is smaller than the size of `u64` | note: required by a bound in `is_transmutable` --> $DIR/primitive_reprs_should_have_correct_length.rs:12:14 @@ -222,7 +222,7 @@ error[E0277]: `u16` cannot be safely transmuted into `V0u32` --> $DIR/primitive_reprs_should_have_correct_length.rs:98:44 | LL | assert::is_transmutable::<Smaller, Current>(); - | ^^^^^^^ The size of `u16` is smaller than the size of `V0u32` + | ^^^^^^^ the size of `u16` is smaller than the size of `V0u32` | note: required by a bound in `is_transmutable` --> $DIR/primitive_reprs_should_have_correct_length.rs:12:14 @@ -244,7 +244,7 @@ error[E0277]: `V0u32` cannot be safely transmuted into `u64` --> $DIR/primitive_reprs_should_have_correct_length.rs:100:44 | LL | assert::is_transmutable::<Current, Larger>(); - | ^^^^^^ The size of `V0u32` is smaller than the size of `u64` + | ^^^^^^ the size of `V0u32` is smaller than the size of `u64` | note: required by a bound in `is_transmutable` --> $DIR/primitive_reprs_should_have_correct_length.rs:12:14 @@ -266,7 +266,7 @@ error[E0277]: `u32` cannot be safely transmuted into `V0i64` --> $DIR/primitive_reprs_should_have_correct_length.rs:112:44 | LL | assert::is_transmutable::<Smaller, Current>(); - | ^^^^^^^ The size of `u32` is smaller than the size of `V0i64` + | ^^^^^^^ the size of `u32` is smaller than the size of `V0i64` | note: required by a bound in `is_transmutable` --> $DIR/primitive_reprs_should_have_correct_length.rs:12:14 @@ -288,7 +288,7 @@ error[E0277]: `V0i64` cannot be safely transmuted into `u128` --> $DIR/primitive_reprs_should_have_correct_length.rs:114:44 | LL | assert::is_transmutable::<Current, Larger>(); - | ^^^^^^ The size of `V0i64` is smaller than the size of `u128` + | ^^^^^^ the size of `V0i64` is smaller than the size of `u128` | note: required by a bound in `is_transmutable` --> $DIR/primitive_reprs_should_have_correct_length.rs:12:14 @@ -310,7 +310,7 @@ error[E0277]: `u32` cannot be safely transmuted into `V0u64` --> $DIR/primitive_reprs_should_have_correct_length.rs:120:44 | LL | assert::is_transmutable::<Smaller, Current>(); - | ^^^^^^^ The size of `u32` is smaller than the size of `V0u64` + | ^^^^^^^ the size of `u32` is smaller than the size of `V0u64` | note: required by a bound in `is_transmutable` --> $DIR/primitive_reprs_should_have_correct_length.rs:12:14 @@ -332,7 +332,7 @@ error[E0277]: `V0u64` cannot be safely transmuted into `u128` --> $DIR/primitive_reprs_should_have_correct_length.rs:122:44 | LL | assert::is_transmutable::<Current, Larger>(); - | ^^^^^^ The size of `V0u64` is smaller than the size of `u128` + | ^^^^^^ the size of `V0u64` is smaller than the size of `u128` | note: required by a bound in `is_transmutable` --> $DIR/primitive_reprs_should_have_correct_length.rs:12:14 @@ -354,7 +354,7 @@ error[E0277]: `u8` cannot be safely transmuted into `V0isize` --> $DIR/primitive_reprs_should_have_correct_length.rs:134:44 | LL | assert::is_transmutable::<Smaller, Current>(); - | ^^^^^^^ The size of `u8` is smaller than the size of `V0isize` + | ^^^^^^^ the size of `u8` is smaller than the size of `V0isize` | note: required by a bound in `is_transmutable` --> $DIR/primitive_reprs_should_have_correct_length.rs:12:14 @@ -376,7 +376,7 @@ error[E0277]: `V0isize` cannot be safely transmuted into `[usize; 2]` --> $DIR/primitive_reprs_should_have_correct_length.rs:136:44 | LL | assert::is_transmutable::<Current, Larger>(); - | ^^^^^^ The size of `V0isize` is smaller than the size of `[usize; 2]` + | ^^^^^^ the size of `V0isize` is smaller than the size of `[usize; 2]` | note: required by a bound in `is_transmutable` --> $DIR/primitive_reprs_should_have_correct_length.rs:12:14 @@ -398,7 +398,7 @@ error[E0277]: `u8` cannot be safely transmuted into `V0usize` --> $DIR/primitive_reprs_should_have_correct_length.rs:142:44 | LL | assert::is_transmutable::<Smaller, Current>(); - | ^^^^^^^ The size of `u8` is smaller than the size of `V0usize` + | ^^^^^^^ the size of `u8` is smaller than the size of `V0usize` | note: required by a bound in `is_transmutable` --> $DIR/primitive_reprs_should_have_correct_length.rs:12:14 @@ -420,7 +420,7 @@ error[E0277]: `V0usize` cannot be safely transmuted into `[usize; 2]` --> $DIR/primitive_reprs_should_have_correct_length.rs:144:44 | LL | assert::is_transmutable::<Current, Larger>(); - | ^^^^^^ The size of `V0usize` is smaller than the size of `[usize; 2]` + | ^^^^^^ the size of `V0usize` is smaller than the size of `[usize; 2]` | note: required by a bound in `is_transmutable` --> $DIR/primitive_reprs_should_have_correct_length.rs:12:14 diff --git a/tests/ui/transmutability/enums/repr/should_require_well_defined_layout.stderr b/tests/ui/transmutability/enums/repr/should_require_well_defined_layout.stderr index 24730935047..2a683de6a65 100644 --- a/tests/ui/transmutability/enums/repr/should_require_well_defined_layout.stderr +++ b/tests/ui/transmutability/enums/repr/should_require_well_defined_layout.stderr @@ -2,7 +2,7 @@ error[E0277]: `void::repr_rust` cannot be safely transmuted into `()` --> $DIR/should_require_well_defined_layout.rs:27:52 | LL | assert::is_maybe_transmutable::<repr_rust, ()>(); - | ^^ `void::repr_rust` does not have a well-specified layout + | ^^ analyzing the transmutability of `void::repr_rust` is not yet supported. | note: required by a bound in `is_maybe_transmutable` --> $DIR/should_require_well_defined_layout.rs:13:14 @@ -24,7 +24,7 @@ error[E0277]: `u128` cannot be safely transmuted into `void::repr_rust` --> $DIR/should_require_well_defined_layout.rs:28:47 | LL | assert::is_maybe_transmutable::<u128, repr_rust>(); - | ^^^^^^^^^ `void::repr_rust` does not have a well-specified layout + | ^^^^^^^^^ analyzing the transmutability of `void::repr_rust` is not yet supported. | note: required by a bound in `is_maybe_transmutable` --> $DIR/should_require_well_defined_layout.rs:13:14 @@ -46,7 +46,7 @@ error[E0277]: `singleton::repr_rust` cannot be safely transmuted into `()` --> $DIR/should_require_well_defined_layout.rs:33:52 | LL | assert::is_maybe_transmutable::<repr_rust, ()>(); - | ^^ `singleton::repr_rust` does not have a well-specified layout + | ^^ analyzing the transmutability of `singleton::repr_rust` is not yet supported. | note: required by a bound in `is_maybe_transmutable` --> $DIR/should_require_well_defined_layout.rs:13:14 @@ -68,7 +68,7 @@ error[E0277]: `u128` cannot be safely transmuted into `singleton::repr_rust` --> $DIR/should_require_well_defined_layout.rs:34:47 | LL | assert::is_maybe_transmutable::<u128, repr_rust>(); - | ^^^^^^^^^ `singleton::repr_rust` does not have a well-specified layout + | ^^^^^^^^^ analyzing the transmutability of `singleton::repr_rust` is not yet supported. | note: required by a bound in `is_maybe_transmutable` --> $DIR/should_require_well_defined_layout.rs:13:14 @@ -90,7 +90,7 @@ error[E0277]: `duplex::repr_rust` cannot be safely transmuted into `()` --> $DIR/should_require_well_defined_layout.rs:39:52 | LL | assert::is_maybe_transmutable::<repr_rust, ()>(); - | ^^ `duplex::repr_rust` does not have a well-specified layout + | ^^ analyzing the transmutability of `duplex::repr_rust` is not yet supported. | note: required by a bound in `is_maybe_transmutable` --> $DIR/should_require_well_defined_layout.rs:13:14 @@ -112,7 +112,7 @@ error[E0277]: `u128` cannot be safely transmuted into `duplex::repr_rust` --> $DIR/should_require_well_defined_layout.rs:40:47 | LL | assert::is_maybe_transmutable::<u128, repr_rust>(); - | ^^^^^^^^^ `duplex::repr_rust` does not have a well-specified layout + | ^^^^^^^^^ analyzing the transmutability of `duplex::repr_rust` is not yet supported. | note: required by a bound in `is_maybe_transmutable` --> $DIR/should_require_well_defined_layout.rs:13:14 diff --git a/tests/ui/transmutability/enums/should_pad_variants.stderr b/tests/ui/transmutability/enums/should_pad_variants.stderr index 13b4c8053ad..da4294bdbce 100644 --- a/tests/ui/transmutability/enums/should_pad_variants.stderr +++ b/tests/ui/transmutability/enums/should_pad_variants.stderr @@ -2,7 +2,7 @@ error[E0277]: `Src` cannot be safely transmuted into `Dst` --> $DIR/should_pad_variants.rs:43:36 | LL | assert::is_transmutable::<Src, Dst>(); - | ^^^ The size of `Src` is smaller than the size of `Dst` + | ^^^ the size of `Src` is smaller than the size of `Dst` | note: required by a bound in `is_transmutable` --> $DIR/should_pad_variants.rs:13:14 diff --git a/tests/ui/transmutability/enums/should_respect_endianness.stderr b/tests/ui/transmutability/enums/should_respect_endianness.stderr index c2a2eb53458..9f88bb06813 100644 --- a/tests/ui/transmutability/enums/should_respect_endianness.stderr +++ b/tests/ui/transmutability/enums/should_respect_endianness.stderr @@ -2,7 +2,7 @@ error[E0277]: `Src` cannot be safely transmuted into `Unexpected` --> $DIR/should_respect_endianness.rs:35:36 | LL | assert::is_transmutable::<Src, Unexpected>(); - | ^^^^^^^^^^ At least one value of `Src` isn't a bit-valid value of `Unexpected` + | ^^^^^^^^^^ at least one value of `Src` isn't a bit-valid value of `Unexpected` | note: required by a bound in `is_transmutable` --> $DIR/should_respect_endianness.rs:13:14 diff --git a/tests/ui/transmutability/primitives/bool-mut.stderr b/tests/ui/transmutability/primitives/bool-mut.stderr index c4f295fc70a..464c2755e11 100644 --- a/tests/ui/transmutability/primitives/bool-mut.stderr +++ b/tests/ui/transmutability/primitives/bool-mut.stderr @@ -2,7 +2,7 @@ error[E0277]: `u8` cannot be safely transmuted into `bool` --> $DIR/bool-mut.rs:15:50 | LL | assert::is_transmutable::<&'static mut bool, &'static mut u8>() - | ^^^^^^^^^^^^^^^ At least one value of `u8` isn't a bit-valid value of `bool` + | ^^^^^^^^^^^^^^^ at least one value of `u8` isn't a bit-valid value of `bool` | note: required by a bound in `is_transmutable` --> $DIR/bool-mut.rs:10:14 diff --git a/tests/ui/transmutability/primitives/bool.current.stderr b/tests/ui/transmutability/primitives/bool.current.stderr index 98e4a1029c9..da6a4a44e95 100644 --- a/tests/ui/transmutability/primitives/bool.current.stderr +++ b/tests/ui/transmutability/primitives/bool.current.stderr @@ -2,7 +2,7 @@ error[E0277]: `u8` cannot be safely transmuted into `bool` --> $DIR/bool.rs:21:35 | LL | assert::is_transmutable::<u8, bool>(); - | ^^^^ At least one value of `u8` isn't a bit-valid value of `bool` + | ^^^^ at least one value of `u8` isn't a bit-valid value of `bool` | note: required by a bound in `is_transmutable` --> $DIR/bool.rs:11:14 diff --git a/tests/ui/transmutability/primitives/bool.next.stderr b/tests/ui/transmutability/primitives/bool.next.stderr index 98e4a1029c9..da6a4a44e95 100644 --- a/tests/ui/transmutability/primitives/bool.next.stderr +++ b/tests/ui/transmutability/primitives/bool.next.stderr @@ -2,7 +2,7 @@ error[E0277]: `u8` cannot be safely transmuted into `bool` --> $DIR/bool.rs:21:35 | LL | assert::is_transmutable::<u8, bool>(); - | ^^^^ At least one value of `u8` isn't a bit-valid value of `bool` + | ^^^^ at least one value of `u8` isn't a bit-valid value of `bool` | note: required by a bound in `is_transmutable` --> $DIR/bool.rs:11:14 diff --git a/tests/ui/transmutability/primitives/numbers.current.stderr b/tests/ui/transmutability/primitives/numbers.current.stderr index 7a80e444149..0a9b9d182f8 100644 --- a/tests/ui/transmutability/primitives/numbers.current.stderr +++ b/tests/ui/transmutability/primitives/numbers.current.stderr @@ -2,7 +2,7 @@ error[E0277]: `i8` cannot be safely transmuted into `i16` --> $DIR/numbers.rs:64:40 | LL | assert::is_transmutable::< i8, i16>(); - | ^^^ The size of `i8` is smaller than the size of `i16` + | ^^^ the size of `i8` is smaller than the size of `i16` | note: required by a bound in `is_transmutable` --> $DIR/numbers.rs:14:14 @@ -17,7 +17,7 @@ error[E0277]: `i8` cannot be safely transmuted into `u16` --> $DIR/numbers.rs:65:40 | LL | assert::is_transmutable::< i8, u16>(); - | ^^^ The size of `i8` is smaller than the size of `u16` + | ^^^ the size of `i8` is smaller than the size of `u16` | note: required by a bound in `is_transmutable` --> $DIR/numbers.rs:14:14 @@ -32,7 +32,7 @@ error[E0277]: `i8` cannot be safely transmuted into `i32` --> $DIR/numbers.rs:66:40 | LL | assert::is_transmutable::< i8, i32>(); - | ^^^ The size of `i8` is smaller than the size of `i32` + | ^^^ the size of `i8` is smaller than the size of `i32` | note: required by a bound in `is_transmutable` --> $DIR/numbers.rs:14:14 @@ -47,7 +47,7 @@ error[E0277]: `i8` cannot be safely transmuted into `f32` --> $DIR/numbers.rs:67:40 | LL | assert::is_transmutable::< i8, f32>(); - | ^^^ The size of `i8` is smaller than the size of `f32` + | ^^^ the size of `i8` is smaller than the size of `f32` | note: required by a bound in `is_transmutable` --> $DIR/numbers.rs:14:14 @@ -62,7 +62,7 @@ error[E0277]: `i8` cannot be safely transmuted into `u32` --> $DIR/numbers.rs:68:40 | LL | assert::is_transmutable::< i8, u32>(); - | ^^^ The size of `i8` is smaller than the size of `u32` + | ^^^ the size of `i8` is smaller than the size of `u32` | note: required by a bound in `is_transmutable` --> $DIR/numbers.rs:14:14 @@ -77,7 +77,7 @@ error[E0277]: `i8` cannot be safely transmuted into `u64` --> $DIR/numbers.rs:69:40 | LL | assert::is_transmutable::< i8, u64>(); - | ^^^ The size of `i8` is smaller than the size of `u64` + | ^^^ the size of `i8` is smaller than the size of `u64` | note: required by a bound in `is_transmutable` --> $DIR/numbers.rs:14:14 @@ -92,7 +92,7 @@ error[E0277]: `i8` cannot be safely transmuted into `i64` --> $DIR/numbers.rs:70:40 | LL | assert::is_transmutable::< i8, i64>(); - | ^^^ The size of `i8` is smaller than the size of `i64` + | ^^^ the size of `i8` is smaller than the size of `i64` | note: required by a bound in `is_transmutable` --> $DIR/numbers.rs:14:14 @@ -107,7 +107,7 @@ error[E0277]: `i8` cannot be safely transmuted into `f64` --> $DIR/numbers.rs:71:40 | LL | assert::is_transmutable::< i8, f64>(); - | ^^^ The size of `i8` is smaller than the size of `f64` + | ^^^ the size of `i8` is smaller than the size of `f64` | note: required by a bound in `is_transmutable` --> $DIR/numbers.rs:14:14 @@ -122,7 +122,7 @@ error[E0277]: `i8` cannot be safely transmuted into `u128` --> $DIR/numbers.rs:72:39 | LL | assert::is_transmutable::< i8, u128>(); - | ^^^^ The size of `i8` is smaller than the size of `u128` + | ^^^^ the size of `i8` is smaller than the size of `u128` | note: required by a bound in `is_transmutable` --> $DIR/numbers.rs:14:14 @@ -137,7 +137,7 @@ error[E0277]: `i8` cannot be safely transmuted into `i128` --> $DIR/numbers.rs:73:39 | LL | assert::is_transmutable::< i8, i128>(); - | ^^^^ The size of `i8` is smaller than the size of `i128` + | ^^^^ the size of `i8` is smaller than the size of `i128` | note: required by a bound in `is_transmutable` --> $DIR/numbers.rs:14:14 @@ -152,7 +152,7 @@ error[E0277]: `u8` cannot be safely transmuted into `i16` --> $DIR/numbers.rs:75:40 | LL | assert::is_transmutable::< u8, i16>(); - | ^^^ The size of `u8` is smaller than the size of `i16` + | ^^^ the size of `u8` is smaller than the size of `i16` | note: required by a bound in `is_transmutable` --> $DIR/numbers.rs:14:14 @@ -167,7 +167,7 @@ error[E0277]: `u8` cannot be safely transmuted into `u16` --> $DIR/numbers.rs:76:40 | LL | assert::is_transmutable::< u8, u16>(); - | ^^^ The size of `u8` is smaller than the size of `u16` + | ^^^ the size of `u8` is smaller than the size of `u16` | note: required by a bound in `is_transmutable` --> $DIR/numbers.rs:14:14 @@ -182,7 +182,7 @@ error[E0277]: `u8` cannot be safely transmuted into `i32` --> $DIR/numbers.rs:77:40 | LL | assert::is_transmutable::< u8, i32>(); - | ^^^ The size of `u8` is smaller than the size of `i32` + | ^^^ the size of `u8` is smaller than the size of `i32` | note: required by a bound in `is_transmutable` --> $DIR/numbers.rs:14:14 @@ -197,7 +197,7 @@ error[E0277]: `u8` cannot be safely transmuted into `f32` --> $DIR/numbers.rs:78:40 | LL | assert::is_transmutable::< u8, f32>(); - | ^^^ The size of `u8` is smaller than the size of `f32` + | ^^^ the size of `u8` is smaller than the size of `f32` | note: required by a bound in `is_transmutable` --> $DIR/numbers.rs:14:14 @@ -212,7 +212,7 @@ error[E0277]: `u8` cannot be safely transmuted into `u32` --> $DIR/numbers.rs:79:40 | LL | assert::is_transmutable::< u8, u32>(); - | ^^^ The size of `u8` is smaller than the size of `u32` + | ^^^ the size of `u8` is smaller than the size of `u32` | note: required by a bound in `is_transmutable` --> $DIR/numbers.rs:14:14 @@ -227,7 +227,7 @@ error[E0277]: `u8` cannot be safely transmuted into `u64` --> $DIR/numbers.rs:80:40 | LL | assert::is_transmutable::< u8, u64>(); - | ^^^ The size of `u8` is smaller than the size of `u64` + | ^^^ the size of `u8` is smaller than the size of `u64` | note: required by a bound in `is_transmutable` --> $DIR/numbers.rs:14:14 @@ -242,7 +242,7 @@ error[E0277]: `u8` cannot be safely transmuted into `i64` --> $DIR/numbers.rs:81:40 | LL | assert::is_transmutable::< u8, i64>(); - | ^^^ The size of `u8` is smaller than the size of `i64` + | ^^^ the size of `u8` is smaller than the size of `i64` | note: required by a bound in `is_transmutable` --> $DIR/numbers.rs:14:14 @@ -257,7 +257,7 @@ error[E0277]: `u8` cannot be safely transmuted into `f64` --> $DIR/numbers.rs:82:40 | LL | assert::is_transmutable::< u8, f64>(); - | ^^^ The size of `u8` is smaller than the size of `f64` + | ^^^ the size of `u8` is smaller than the size of `f64` | note: required by a bound in `is_transmutable` --> $DIR/numbers.rs:14:14 @@ -272,7 +272,7 @@ error[E0277]: `u8` cannot be safely transmuted into `u128` --> $DIR/numbers.rs:83:39 | LL | assert::is_transmutable::< u8, u128>(); - | ^^^^ The size of `u8` is smaller than the size of `u128` + | ^^^^ the size of `u8` is smaller than the size of `u128` | note: required by a bound in `is_transmutable` --> $DIR/numbers.rs:14:14 @@ -287,7 +287,7 @@ error[E0277]: `u8` cannot be safely transmuted into `i128` --> $DIR/numbers.rs:84:39 | LL | assert::is_transmutable::< u8, i128>(); - | ^^^^ The size of `u8` is smaller than the size of `i128` + | ^^^^ the size of `u8` is smaller than the size of `i128` | note: required by a bound in `is_transmutable` --> $DIR/numbers.rs:14:14 @@ -302,7 +302,7 @@ error[E0277]: `i16` cannot be safely transmuted into `i32` --> $DIR/numbers.rs:86:40 | LL | assert::is_transmutable::< i16, i32>(); - | ^^^ The size of `i16` is smaller than the size of `i32` + | ^^^ the size of `i16` is smaller than the size of `i32` | note: required by a bound in `is_transmutable` --> $DIR/numbers.rs:14:14 @@ -317,7 +317,7 @@ error[E0277]: `i16` cannot be safely transmuted into `f32` --> $DIR/numbers.rs:87:40 | LL | assert::is_transmutable::< i16, f32>(); - | ^^^ The size of `i16` is smaller than the size of `f32` + | ^^^ the size of `i16` is smaller than the size of `f32` | note: required by a bound in `is_transmutable` --> $DIR/numbers.rs:14:14 @@ -332,7 +332,7 @@ error[E0277]: `i16` cannot be safely transmuted into `u32` --> $DIR/numbers.rs:88:40 | LL | assert::is_transmutable::< i16, u32>(); - | ^^^ The size of `i16` is smaller than the size of `u32` + | ^^^ the size of `i16` is smaller than the size of `u32` | note: required by a bound in `is_transmutable` --> $DIR/numbers.rs:14:14 @@ -347,7 +347,7 @@ error[E0277]: `i16` cannot be safely transmuted into `u64` --> $DIR/numbers.rs:89:40 | LL | assert::is_transmutable::< i16, u64>(); - | ^^^ The size of `i16` is smaller than the size of `u64` + | ^^^ the size of `i16` is smaller than the size of `u64` | note: required by a bound in `is_transmutable` --> $DIR/numbers.rs:14:14 @@ -362,7 +362,7 @@ error[E0277]: `i16` cannot be safely transmuted into `i64` --> $DIR/numbers.rs:90:40 | LL | assert::is_transmutable::< i16, i64>(); - | ^^^ The size of `i16` is smaller than the size of `i64` + | ^^^ the size of `i16` is smaller than the size of `i64` | note: required by a bound in `is_transmutable` --> $DIR/numbers.rs:14:14 @@ -377,7 +377,7 @@ error[E0277]: `i16` cannot be safely transmuted into `f64` --> $DIR/numbers.rs:91:40 | LL | assert::is_transmutable::< i16, f64>(); - | ^^^ The size of `i16` is smaller than the size of `f64` + | ^^^ the size of `i16` is smaller than the size of `f64` | note: required by a bound in `is_transmutable` --> $DIR/numbers.rs:14:14 @@ -392,7 +392,7 @@ error[E0277]: `i16` cannot be safely transmuted into `u128` --> $DIR/numbers.rs:92:39 | LL | assert::is_transmutable::< i16, u128>(); - | ^^^^ The size of `i16` is smaller than the size of `u128` + | ^^^^ the size of `i16` is smaller than the size of `u128` | note: required by a bound in `is_transmutable` --> $DIR/numbers.rs:14:14 @@ -407,7 +407,7 @@ error[E0277]: `i16` cannot be safely transmuted into `i128` --> $DIR/numbers.rs:93:39 | LL | assert::is_transmutable::< i16, i128>(); - | ^^^^ The size of `i16` is smaller than the size of `i128` + | ^^^^ the size of `i16` is smaller than the size of `i128` | note: required by a bound in `is_transmutable` --> $DIR/numbers.rs:14:14 @@ -422,7 +422,7 @@ error[E0277]: `u16` cannot be safely transmuted into `i32` --> $DIR/numbers.rs:95:40 | LL | assert::is_transmutable::< u16, i32>(); - | ^^^ The size of `u16` is smaller than the size of `i32` + | ^^^ the size of `u16` is smaller than the size of `i32` | note: required by a bound in `is_transmutable` --> $DIR/numbers.rs:14:14 @@ -437,7 +437,7 @@ error[E0277]: `u16` cannot be safely transmuted into `f32` --> $DIR/numbers.rs:96:40 | LL | assert::is_transmutable::< u16, f32>(); - | ^^^ The size of `u16` is smaller than the size of `f32` + | ^^^ the size of `u16` is smaller than the size of `f32` | note: required by a bound in `is_transmutable` --> $DIR/numbers.rs:14:14 @@ -452,7 +452,7 @@ error[E0277]: `u16` cannot be safely transmuted into `u32` --> $DIR/numbers.rs:97:40 | LL | assert::is_transmutable::< u16, u32>(); - | ^^^ The size of `u16` is smaller than the size of `u32` + | ^^^ the size of `u16` is smaller than the size of `u32` | note: required by a bound in `is_transmutable` --> $DIR/numbers.rs:14:14 @@ -467,7 +467,7 @@ error[E0277]: `u16` cannot be safely transmuted into `u64` --> $DIR/numbers.rs:98:40 | LL | assert::is_transmutable::< u16, u64>(); - | ^^^ The size of `u16` is smaller than the size of `u64` + | ^^^ the size of `u16` is smaller than the size of `u64` | note: required by a bound in `is_transmutable` --> $DIR/numbers.rs:14:14 @@ -482,7 +482,7 @@ error[E0277]: `u16` cannot be safely transmuted into `i64` --> $DIR/numbers.rs:99:40 | LL | assert::is_transmutable::< u16, i64>(); - | ^^^ The size of `u16` is smaller than the size of `i64` + | ^^^ the size of `u16` is smaller than the size of `i64` | note: required by a bound in `is_transmutable` --> $DIR/numbers.rs:14:14 @@ -497,7 +497,7 @@ error[E0277]: `u16` cannot be safely transmuted into `f64` --> $DIR/numbers.rs:100:40 | LL | assert::is_transmutable::< u16, f64>(); - | ^^^ The size of `u16` is smaller than the size of `f64` + | ^^^ the size of `u16` is smaller than the size of `f64` | note: required by a bound in `is_transmutable` --> $DIR/numbers.rs:14:14 @@ -512,7 +512,7 @@ error[E0277]: `u16` cannot be safely transmuted into `u128` --> $DIR/numbers.rs:101:39 | LL | assert::is_transmutable::< u16, u128>(); - | ^^^^ The size of `u16` is smaller than the size of `u128` + | ^^^^ the size of `u16` is smaller than the size of `u128` | note: required by a bound in `is_transmutable` --> $DIR/numbers.rs:14:14 @@ -527,7 +527,7 @@ error[E0277]: `u16` cannot be safely transmuted into `i128` --> $DIR/numbers.rs:102:39 | LL | assert::is_transmutable::< u16, i128>(); - | ^^^^ The size of `u16` is smaller than the size of `i128` + | ^^^^ the size of `u16` is smaller than the size of `i128` | note: required by a bound in `is_transmutable` --> $DIR/numbers.rs:14:14 @@ -542,7 +542,7 @@ error[E0277]: `i32` cannot be safely transmuted into `u64` --> $DIR/numbers.rs:104:40 | LL | assert::is_transmutable::< i32, u64>(); - | ^^^ The size of `i32` is smaller than the size of `u64` + | ^^^ the size of `i32` is smaller than the size of `u64` | note: required by a bound in `is_transmutable` --> $DIR/numbers.rs:14:14 @@ -557,7 +557,7 @@ error[E0277]: `i32` cannot be safely transmuted into `i64` --> $DIR/numbers.rs:105:40 | LL | assert::is_transmutable::< i32, i64>(); - | ^^^ The size of `i32` is smaller than the size of `i64` + | ^^^ the size of `i32` is smaller than the size of `i64` | note: required by a bound in `is_transmutable` --> $DIR/numbers.rs:14:14 @@ -572,7 +572,7 @@ error[E0277]: `i32` cannot be safely transmuted into `f64` --> $DIR/numbers.rs:106:40 | LL | assert::is_transmutable::< i32, f64>(); - | ^^^ The size of `i32` is smaller than the size of `f64` + | ^^^ the size of `i32` is smaller than the size of `f64` | note: required by a bound in `is_transmutable` --> $DIR/numbers.rs:14:14 @@ -587,7 +587,7 @@ error[E0277]: `i32` cannot be safely transmuted into `u128` --> $DIR/numbers.rs:107:39 | LL | assert::is_transmutable::< i32, u128>(); - | ^^^^ The size of `i32` is smaller than the size of `u128` + | ^^^^ the size of `i32` is smaller than the size of `u128` | note: required by a bound in `is_transmutable` --> $DIR/numbers.rs:14:14 @@ -602,7 +602,7 @@ error[E0277]: `i32` cannot be safely transmuted into `i128` --> $DIR/numbers.rs:108:39 | LL | assert::is_transmutable::< i32, i128>(); - | ^^^^ The size of `i32` is smaller than the size of `i128` + | ^^^^ the size of `i32` is smaller than the size of `i128` | note: required by a bound in `is_transmutable` --> $DIR/numbers.rs:14:14 @@ -617,7 +617,7 @@ error[E0277]: `f32` cannot be safely transmuted into `u64` --> $DIR/numbers.rs:110:40 | LL | assert::is_transmutable::< f32, u64>(); - | ^^^ The size of `f32` is smaller than the size of `u64` + | ^^^ the size of `f32` is smaller than the size of `u64` | note: required by a bound in `is_transmutable` --> $DIR/numbers.rs:14:14 @@ -632,7 +632,7 @@ error[E0277]: `f32` cannot be safely transmuted into `i64` --> $DIR/numbers.rs:111:40 | LL | assert::is_transmutable::< f32, i64>(); - | ^^^ The size of `f32` is smaller than the size of `i64` + | ^^^ the size of `f32` is smaller than the size of `i64` | note: required by a bound in `is_transmutable` --> $DIR/numbers.rs:14:14 @@ -647,7 +647,7 @@ error[E0277]: `f32` cannot be safely transmuted into `f64` --> $DIR/numbers.rs:112:40 | LL | assert::is_transmutable::< f32, f64>(); - | ^^^ The size of `f32` is smaller than the size of `f64` + | ^^^ the size of `f32` is smaller than the size of `f64` | note: required by a bound in `is_transmutable` --> $DIR/numbers.rs:14:14 @@ -662,7 +662,7 @@ error[E0277]: `f32` cannot be safely transmuted into `u128` --> $DIR/numbers.rs:113:39 | LL | assert::is_transmutable::< f32, u128>(); - | ^^^^ The size of `f32` is smaller than the size of `u128` + | ^^^^ the size of `f32` is smaller than the size of `u128` | note: required by a bound in `is_transmutable` --> $DIR/numbers.rs:14:14 @@ -677,7 +677,7 @@ error[E0277]: `f32` cannot be safely transmuted into `i128` --> $DIR/numbers.rs:114:39 | LL | assert::is_transmutable::< f32, i128>(); - | ^^^^ The size of `f32` is smaller than the size of `i128` + | ^^^^ the size of `f32` is smaller than the size of `i128` | note: required by a bound in `is_transmutable` --> $DIR/numbers.rs:14:14 @@ -692,7 +692,7 @@ error[E0277]: `u32` cannot be safely transmuted into `u64` --> $DIR/numbers.rs:116:40 | LL | assert::is_transmutable::< u32, u64>(); - | ^^^ The size of `u32` is smaller than the size of `u64` + | ^^^ the size of `u32` is smaller than the size of `u64` | note: required by a bound in `is_transmutable` --> $DIR/numbers.rs:14:14 @@ -707,7 +707,7 @@ error[E0277]: `u32` cannot be safely transmuted into `i64` --> $DIR/numbers.rs:117:40 | LL | assert::is_transmutable::< u32, i64>(); - | ^^^ The size of `u32` is smaller than the size of `i64` + | ^^^ the size of `u32` is smaller than the size of `i64` | note: required by a bound in `is_transmutable` --> $DIR/numbers.rs:14:14 @@ -722,7 +722,7 @@ error[E0277]: `u32` cannot be safely transmuted into `f64` --> $DIR/numbers.rs:118:40 | LL | assert::is_transmutable::< u32, f64>(); - | ^^^ The size of `u32` is smaller than the size of `f64` + | ^^^ the size of `u32` is smaller than the size of `f64` | note: required by a bound in `is_transmutable` --> $DIR/numbers.rs:14:14 @@ -737,7 +737,7 @@ error[E0277]: `u32` cannot be safely transmuted into `u128` --> $DIR/numbers.rs:119:39 | LL | assert::is_transmutable::< u32, u128>(); - | ^^^^ The size of `u32` is smaller than the size of `u128` + | ^^^^ the size of `u32` is smaller than the size of `u128` | note: required by a bound in `is_transmutable` --> $DIR/numbers.rs:14:14 @@ -752,7 +752,7 @@ error[E0277]: `u32` cannot be safely transmuted into `i128` --> $DIR/numbers.rs:120:39 | LL | assert::is_transmutable::< u32, i128>(); - | ^^^^ The size of `u32` is smaller than the size of `i128` + | ^^^^ the size of `u32` is smaller than the size of `i128` | note: required by a bound in `is_transmutable` --> $DIR/numbers.rs:14:14 @@ -767,7 +767,7 @@ error[E0277]: `u64` cannot be safely transmuted into `u128` --> $DIR/numbers.rs:122:39 | LL | assert::is_transmutable::< u64, u128>(); - | ^^^^ The size of `u64` is smaller than the size of `u128` + | ^^^^ the size of `u64` is smaller than the size of `u128` | note: required by a bound in `is_transmutable` --> $DIR/numbers.rs:14:14 @@ -782,7 +782,7 @@ error[E0277]: `u64` cannot be safely transmuted into `i128` --> $DIR/numbers.rs:123:39 | LL | assert::is_transmutable::< u64, i128>(); - | ^^^^ The size of `u64` is smaller than the size of `i128` + | ^^^^ the size of `u64` is smaller than the size of `i128` | note: required by a bound in `is_transmutable` --> $DIR/numbers.rs:14:14 @@ -797,7 +797,7 @@ error[E0277]: `i64` cannot be safely transmuted into `u128` --> $DIR/numbers.rs:125:39 | LL | assert::is_transmutable::< i64, u128>(); - | ^^^^ The size of `i64` is smaller than the size of `u128` + | ^^^^ the size of `i64` is smaller than the size of `u128` | note: required by a bound in `is_transmutable` --> $DIR/numbers.rs:14:14 @@ -812,7 +812,7 @@ error[E0277]: `i64` cannot be safely transmuted into `i128` --> $DIR/numbers.rs:126:39 | LL | assert::is_transmutable::< i64, i128>(); - | ^^^^ The size of `i64` is smaller than the size of `i128` + | ^^^^ the size of `i64` is smaller than the size of `i128` | note: required by a bound in `is_transmutable` --> $DIR/numbers.rs:14:14 @@ -827,7 +827,7 @@ error[E0277]: `f64` cannot be safely transmuted into `u128` --> $DIR/numbers.rs:128:39 | LL | assert::is_transmutable::< f64, u128>(); - | ^^^^ The size of `f64` is smaller than the size of `u128` + | ^^^^ the size of `f64` is smaller than the size of `u128` | note: required by a bound in `is_transmutable` --> $DIR/numbers.rs:14:14 @@ -842,7 +842,7 @@ error[E0277]: `f64` cannot be safely transmuted into `i128` --> $DIR/numbers.rs:129:39 | LL | assert::is_transmutable::< f64, i128>(); - | ^^^^ The size of `f64` is smaller than the size of `i128` + | ^^^^ the size of `f64` is smaller than the size of `i128` | note: required by a bound in `is_transmutable` --> $DIR/numbers.rs:14:14 diff --git a/tests/ui/transmutability/primitives/numbers.next.stderr b/tests/ui/transmutability/primitives/numbers.next.stderr index 7a80e444149..0a9b9d182f8 100644 --- a/tests/ui/transmutability/primitives/numbers.next.stderr +++ b/tests/ui/transmutability/primitives/numbers.next.stderr @@ -2,7 +2,7 @@ error[E0277]: `i8` cannot be safely transmuted into `i16` --> $DIR/numbers.rs:64:40 | LL | assert::is_transmutable::< i8, i16>(); - | ^^^ The size of `i8` is smaller than the size of `i16` + | ^^^ the size of `i8` is smaller than the size of `i16` | note: required by a bound in `is_transmutable` --> $DIR/numbers.rs:14:14 @@ -17,7 +17,7 @@ error[E0277]: `i8` cannot be safely transmuted into `u16` --> $DIR/numbers.rs:65:40 | LL | assert::is_transmutable::< i8, u16>(); - | ^^^ The size of `i8` is smaller than the size of `u16` + | ^^^ the size of `i8` is smaller than the size of `u16` | note: required by a bound in `is_transmutable` --> $DIR/numbers.rs:14:14 @@ -32,7 +32,7 @@ error[E0277]: `i8` cannot be safely transmuted into `i32` --> $DIR/numbers.rs:66:40 | LL | assert::is_transmutable::< i8, i32>(); - | ^^^ The size of `i8` is smaller than the size of `i32` + | ^^^ the size of `i8` is smaller than the size of `i32` | note: required by a bound in `is_transmutable` --> $DIR/numbers.rs:14:14 @@ -47,7 +47,7 @@ error[E0277]: `i8` cannot be safely transmuted into `f32` --> $DIR/numbers.rs:67:40 | LL | assert::is_transmutable::< i8, f32>(); - | ^^^ The size of `i8` is smaller than the size of `f32` + | ^^^ the size of `i8` is smaller than the size of `f32` | note: required by a bound in `is_transmutable` --> $DIR/numbers.rs:14:14 @@ -62,7 +62,7 @@ error[E0277]: `i8` cannot be safely transmuted into `u32` --> $DIR/numbers.rs:68:40 | LL | assert::is_transmutable::< i8, u32>(); - | ^^^ The size of `i8` is smaller than the size of `u32` + | ^^^ the size of `i8` is smaller than the size of `u32` | note: required by a bound in `is_transmutable` --> $DIR/numbers.rs:14:14 @@ -77,7 +77,7 @@ error[E0277]: `i8` cannot be safely transmuted into `u64` --> $DIR/numbers.rs:69:40 | LL | assert::is_transmutable::< i8, u64>(); - | ^^^ The size of `i8` is smaller than the size of `u64` + | ^^^ the size of `i8` is smaller than the size of `u64` | note: required by a bound in `is_transmutable` --> $DIR/numbers.rs:14:14 @@ -92,7 +92,7 @@ error[E0277]: `i8` cannot be safely transmuted into `i64` --> $DIR/numbers.rs:70:40 | LL | assert::is_transmutable::< i8, i64>(); - | ^^^ The size of `i8` is smaller than the size of `i64` + | ^^^ the size of `i8` is smaller than the size of `i64` | note: required by a bound in `is_transmutable` --> $DIR/numbers.rs:14:14 @@ -107,7 +107,7 @@ error[E0277]: `i8` cannot be safely transmuted into `f64` --> $DIR/numbers.rs:71:40 | LL | assert::is_transmutable::< i8, f64>(); - | ^^^ The size of `i8` is smaller than the size of `f64` + | ^^^ the size of `i8` is smaller than the size of `f64` | note: required by a bound in `is_transmutable` --> $DIR/numbers.rs:14:14 @@ -122,7 +122,7 @@ error[E0277]: `i8` cannot be safely transmuted into `u128` --> $DIR/numbers.rs:72:39 | LL | assert::is_transmutable::< i8, u128>(); - | ^^^^ The size of `i8` is smaller than the size of `u128` + | ^^^^ the size of `i8` is smaller than the size of `u128` | note: required by a bound in `is_transmutable` --> $DIR/numbers.rs:14:14 @@ -137,7 +137,7 @@ error[E0277]: `i8` cannot be safely transmuted into `i128` --> $DIR/numbers.rs:73:39 | LL | assert::is_transmutable::< i8, i128>(); - | ^^^^ The size of `i8` is smaller than the size of `i128` + | ^^^^ the size of `i8` is smaller than the size of `i128` | note: required by a bound in `is_transmutable` --> $DIR/numbers.rs:14:14 @@ -152,7 +152,7 @@ error[E0277]: `u8` cannot be safely transmuted into `i16` --> $DIR/numbers.rs:75:40 | LL | assert::is_transmutable::< u8, i16>(); - | ^^^ The size of `u8` is smaller than the size of `i16` + | ^^^ the size of `u8` is smaller than the size of `i16` | note: required by a bound in `is_transmutable` --> $DIR/numbers.rs:14:14 @@ -167,7 +167,7 @@ error[E0277]: `u8` cannot be safely transmuted into `u16` --> $DIR/numbers.rs:76:40 | LL | assert::is_transmutable::< u8, u16>(); - | ^^^ The size of `u8` is smaller than the size of `u16` + | ^^^ the size of `u8` is smaller than the size of `u16` | note: required by a bound in `is_transmutable` --> $DIR/numbers.rs:14:14 @@ -182,7 +182,7 @@ error[E0277]: `u8` cannot be safely transmuted into `i32` --> $DIR/numbers.rs:77:40 | LL | assert::is_transmutable::< u8, i32>(); - | ^^^ The size of `u8` is smaller than the size of `i32` + | ^^^ the size of `u8` is smaller than the size of `i32` | note: required by a bound in `is_transmutable` --> $DIR/numbers.rs:14:14 @@ -197,7 +197,7 @@ error[E0277]: `u8` cannot be safely transmuted into `f32` --> $DIR/numbers.rs:78:40 | LL | assert::is_transmutable::< u8, f32>(); - | ^^^ The size of `u8` is smaller than the size of `f32` + | ^^^ the size of `u8` is smaller than the size of `f32` | note: required by a bound in `is_transmutable` --> $DIR/numbers.rs:14:14 @@ -212,7 +212,7 @@ error[E0277]: `u8` cannot be safely transmuted into `u32` --> $DIR/numbers.rs:79:40 | LL | assert::is_transmutable::< u8, u32>(); - | ^^^ The size of `u8` is smaller than the size of `u32` + | ^^^ the size of `u8` is smaller than the size of `u32` | note: required by a bound in `is_transmutable` --> $DIR/numbers.rs:14:14 @@ -227,7 +227,7 @@ error[E0277]: `u8` cannot be safely transmuted into `u64` --> $DIR/numbers.rs:80:40 | LL | assert::is_transmutable::< u8, u64>(); - | ^^^ The size of `u8` is smaller than the size of `u64` + | ^^^ the size of `u8` is smaller than the size of `u64` | note: required by a bound in `is_transmutable` --> $DIR/numbers.rs:14:14 @@ -242,7 +242,7 @@ error[E0277]: `u8` cannot be safely transmuted into `i64` --> $DIR/numbers.rs:81:40 | LL | assert::is_transmutable::< u8, i64>(); - | ^^^ The size of `u8` is smaller than the size of `i64` + | ^^^ the size of `u8` is smaller than the size of `i64` | note: required by a bound in `is_transmutable` --> $DIR/numbers.rs:14:14 @@ -257,7 +257,7 @@ error[E0277]: `u8` cannot be safely transmuted into `f64` --> $DIR/numbers.rs:82:40 | LL | assert::is_transmutable::< u8, f64>(); - | ^^^ The size of `u8` is smaller than the size of `f64` + | ^^^ the size of `u8` is smaller than the size of `f64` | note: required by a bound in `is_transmutable` --> $DIR/numbers.rs:14:14 @@ -272,7 +272,7 @@ error[E0277]: `u8` cannot be safely transmuted into `u128` --> $DIR/numbers.rs:83:39 | LL | assert::is_transmutable::< u8, u128>(); - | ^^^^ The size of `u8` is smaller than the size of `u128` + | ^^^^ the size of `u8` is smaller than the size of `u128` | note: required by a bound in `is_transmutable` --> $DIR/numbers.rs:14:14 @@ -287,7 +287,7 @@ error[E0277]: `u8` cannot be safely transmuted into `i128` --> $DIR/numbers.rs:84:39 | LL | assert::is_transmutable::< u8, i128>(); - | ^^^^ The size of `u8` is smaller than the size of `i128` + | ^^^^ the size of `u8` is smaller than the size of `i128` | note: required by a bound in `is_transmutable` --> $DIR/numbers.rs:14:14 @@ -302,7 +302,7 @@ error[E0277]: `i16` cannot be safely transmuted into `i32` --> $DIR/numbers.rs:86:40 | LL | assert::is_transmutable::< i16, i32>(); - | ^^^ The size of `i16` is smaller than the size of `i32` + | ^^^ the size of `i16` is smaller than the size of `i32` | note: required by a bound in `is_transmutable` --> $DIR/numbers.rs:14:14 @@ -317,7 +317,7 @@ error[E0277]: `i16` cannot be safely transmuted into `f32` --> $DIR/numbers.rs:87:40 | LL | assert::is_transmutable::< i16, f32>(); - | ^^^ The size of `i16` is smaller than the size of `f32` + | ^^^ the size of `i16` is smaller than the size of `f32` | note: required by a bound in `is_transmutable` --> $DIR/numbers.rs:14:14 @@ -332,7 +332,7 @@ error[E0277]: `i16` cannot be safely transmuted into `u32` --> $DIR/numbers.rs:88:40 | LL | assert::is_transmutable::< i16, u32>(); - | ^^^ The size of `i16` is smaller than the size of `u32` + | ^^^ the size of `i16` is smaller than the size of `u32` | note: required by a bound in `is_transmutable` --> $DIR/numbers.rs:14:14 @@ -347,7 +347,7 @@ error[E0277]: `i16` cannot be safely transmuted into `u64` --> $DIR/numbers.rs:89:40 | LL | assert::is_transmutable::< i16, u64>(); - | ^^^ The size of `i16` is smaller than the size of `u64` + | ^^^ the size of `i16` is smaller than the size of `u64` | note: required by a bound in `is_transmutable` --> $DIR/numbers.rs:14:14 @@ -362,7 +362,7 @@ error[E0277]: `i16` cannot be safely transmuted into `i64` --> $DIR/numbers.rs:90:40 | LL | assert::is_transmutable::< i16, i64>(); - | ^^^ The size of `i16` is smaller than the size of `i64` + | ^^^ the size of `i16` is smaller than the size of `i64` | note: required by a bound in `is_transmutable` --> $DIR/numbers.rs:14:14 @@ -377,7 +377,7 @@ error[E0277]: `i16` cannot be safely transmuted into `f64` --> $DIR/numbers.rs:91:40 | LL | assert::is_transmutable::< i16, f64>(); - | ^^^ The size of `i16` is smaller than the size of `f64` + | ^^^ the size of `i16` is smaller than the size of `f64` | note: required by a bound in `is_transmutable` --> $DIR/numbers.rs:14:14 @@ -392,7 +392,7 @@ error[E0277]: `i16` cannot be safely transmuted into `u128` --> $DIR/numbers.rs:92:39 | LL | assert::is_transmutable::< i16, u128>(); - | ^^^^ The size of `i16` is smaller than the size of `u128` + | ^^^^ the size of `i16` is smaller than the size of `u128` | note: required by a bound in `is_transmutable` --> $DIR/numbers.rs:14:14 @@ -407,7 +407,7 @@ error[E0277]: `i16` cannot be safely transmuted into `i128` --> $DIR/numbers.rs:93:39 | LL | assert::is_transmutable::< i16, i128>(); - | ^^^^ The size of `i16` is smaller than the size of `i128` + | ^^^^ the size of `i16` is smaller than the size of `i128` | note: required by a bound in `is_transmutable` --> $DIR/numbers.rs:14:14 @@ -422,7 +422,7 @@ error[E0277]: `u16` cannot be safely transmuted into `i32` --> $DIR/numbers.rs:95:40 | LL | assert::is_transmutable::< u16, i32>(); - | ^^^ The size of `u16` is smaller than the size of `i32` + | ^^^ the size of `u16` is smaller than the size of `i32` | note: required by a bound in `is_transmutable` --> $DIR/numbers.rs:14:14 @@ -437,7 +437,7 @@ error[E0277]: `u16` cannot be safely transmuted into `f32` --> $DIR/numbers.rs:96:40 | LL | assert::is_transmutable::< u16, f32>(); - | ^^^ The size of `u16` is smaller than the size of `f32` + | ^^^ the size of `u16` is smaller than the size of `f32` | note: required by a bound in `is_transmutable` --> $DIR/numbers.rs:14:14 @@ -452,7 +452,7 @@ error[E0277]: `u16` cannot be safely transmuted into `u32` --> $DIR/numbers.rs:97:40 | LL | assert::is_transmutable::< u16, u32>(); - | ^^^ The size of `u16` is smaller than the size of `u32` + | ^^^ the size of `u16` is smaller than the size of `u32` | note: required by a bound in `is_transmutable` --> $DIR/numbers.rs:14:14 @@ -467,7 +467,7 @@ error[E0277]: `u16` cannot be safely transmuted into `u64` --> $DIR/numbers.rs:98:40 | LL | assert::is_transmutable::< u16, u64>(); - | ^^^ The size of `u16` is smaller than the size of `u64` + | ^^^ the size of `u16` is smaller than the size of `u64` | note: required by a bound in `is_transmutable` --> $DIR/numbers.rs:14:14 @@ -482,7 +482,7 @@ error[E0277]: `u16` cannot be safely transmuted into `i64` --> $DIR/numbers.rs:99:40 | LL | assert::is_transmutable::< u16, i64>(); - | ^^^ The size of `u16` is smaller than the size of `i64` + | ^^^ the size of `u16` is smaller than the size of `i64` | note: required by a bound in `is_transmutable` --> $DIR/numbers.rs:14:14 @@ -497,7 +497,7 @@ error[E0277]: `u16` cannot be safely transmuted into `f64` --> $DIR/numbers.rs:100:40 | LL | assert::is_transmutable::< u16, f64>(); - | ^^^ The size of `u16` is smaller than the size of `f64` + | ^^^ the size of `u16` is smaller than the size of `f64` | note: required by a bound in `is_transmutable` --> $DIR/numbers.rs:14:14 @@ -512,7 +512,7 @@ error[E0277]: `u16` cannot be safely transmuted into `u128` --> $DIR/numbers.rs:101:39 | LL | assert::is_transmutable::< u16, u128>(); - | ^^^^ The size of `u16` is smaller than the size of `u128` + | ^^^^ the size of `u16` is smaller than the size of `u128` | note: required by a bound in `is_transmutable` --> $DIR/numbers.rs:14:14 @@ -527,7 +527,7 @@ error[E0277]: `u16` cannot be safely transmuted into `i128` --> $DIR/numbers.rs:102:39 | LL | assert::is_transmutable::< u16, i128>(); - | ^^^^ The size of `u16` is smaller than the size of `i128` + | ^^^^ the size of `u16` is smaller than the size of `i128` | note: required by a bound in `is_transmutable` --> $DIR/numbers.rs:14:14 @@ -542,7 +542,7 @@ error[E0277]: `i32` cannot be safely transmuted into `u64` --> $DIR/numbers.rs:104:40 | LL | assert::is_transmutable::< i32, u64>(); - | ^^^ The size of `i32` is smaller than the size of `u64` + | ^^^ the size of `i32` is smaller than the size of `u64` | note: required by a bound in `is_transmutable` --> $DIR/numbers.rs:14:14 @@ -557,7 +557,7 @@ error[E0277]: `i32` cannot be safely transmuted into `i64` --> $DIR/numbers.rs:105:40 | LL | assert::is_transmutable::< i32, i64>(); - | ^^^ The size of `i32` is smaller than the size of `i64` + | ^^^ the size of `i32` is smaller than the size of `i64` | note: required by a bound in `is_transmutable` --> $DIR/numbers.rs:14:14 @@ -572,7 +572,7 @@ error[E0277]: `i32` cannot be safely transmuted into `f64` --> $DIR/numbers.rs:106:40 | LL | assert::is_transmutable::< i32, f64>(); - | ^^^ The size of `i32` is smaller than the size of `f64` + | ^^^ the size of `i32` is smaller than the size of `f64` | note: required by a bound in `is_transmutable` --> $DIR/numbers.rs:14:14 @@ -587,7 +587,7 @@ error[E0277]: `i32` cannot be safely transmuted into `u128` --> $DIR/numbers.rs:107:39 | LL | assert::is_transmutable::< i32, u128>(); - | ^^^^ The size of `i32` is smaller than the size of `u128` + | ^^^^ the size of `i32` is smaller than the size of `u128` | note: required by a bound in `is_transmutable` --> $DIR/numbers.rs:14:14 @@ -602,7 +602,7 @@ error[E0277]: `i32` cannot be safely transmuted into `i128` --> $DIR/numbers.rs:108:39 | LL | assert::is_transmutable::< i32, i128>(); - | ^^^^ The size of `i32` is smaller than the size of `i128` + | ^^^^ the size of `i32` is smaller than the size of `i128` | note: required by a bound in `is_transmutable` --> $DIR/numbers.rs:14:14 @@ -617,7 +617,7 @@ error[E0277]: `f32` cannot be safely transmuted into `u64` --> $DIR/numbers.rs:110:40 | LL | assert::is_transmutable::< f32, u64>(); - | ^^^ The size of `f32` is smaller than the size of `u64` + | ^^^ the size of `f32` is smaller than the size of `u64` | note: required by a bound in `is_transmutable` --> $DIR/numbers.rs:14:14 @@ -632,7 +632,7 @@ error[E0277]: `f32` cannot be safely transmuted into `i64` --> $DIR/numbers.rs:111:40 | LL | assert::is_transmutable::< f32, i64>(); - | ^^^ The size of `f32` is smaller than the size of `i64` + | ^^^ the size of `f32` is smaller than the size of `i64` | note: required by a bound in `is_transmutable` --> $DIR/numbers.rs:14:14 @@ -647,7 +647,7 @@ error[E0277]: `f32` cannot be safely transmuted into `f64` --> $DIR/numbers.rs:112:40 | LL | assert::is_transmutable::< f32, f64>(); - | ^^^ The size of `f32` is smaller than the size of `f64` + | ^^^ the size of `f32` is smaller than the size of `f64` | note: required by a bound in `is_transmutable` --> $DIR/numbers.rs:14:14 @@ -662,7 +662,7 @@ error[E0277]: `f32` cannot be safely transmuted into `u128` --> $DIR/numbers.rs:113:39 | LL | assert::is_transmutable::< f32, u128>(); - | ^^^^ The size of `f32` is smaller than the size of `u128` + | ^^^^ the size of `f32` is smaller than the size of `u128` | note: required by a bound in `is_transmutable` --> $DIR/numbers.rs:14:14 @@ -677,7 +677,7 @@ error[E0277]: `f32` cannot be safely transmuted into `i128` --> $DIR/numbers.rs:114:39 | LL | assert::is_transmutable::< f32, i128>(); - | ^^^^ The size of `f32` is smaller than the size of `i128` + | ^^^^ the size of `f32` is smaller than the size of `i128` | note: required by a bound in `is_transmutable` --> $DIR/numbers.rs:14:14 @@ -692,7 +692,7 @@ error[E0277]: `u32` cannot be safely transmuted into `u64` --> $DIR/numbers.rs:116:40 | LL | assert::is_transmutable::< u32, u64>(); - | ^^^ The size of `u32` is smaller than the size of `u64` + | ^^^ the size of `u32` is smaller than the size of `u64` | note: required by a bound in `is_transmutable` --> $DIR/numbers.rs:14:14 @@ -707,7 +707,7 @@ error[E0277]: `u32` cannot be safely transmuted into `i64` --> $DIR/numbers.rs:117:40 | LL | assert::is_transmutable::< u32, i64>(); - | ^^^ The size of `u32` is smaller than the size of `i64` + | ^^^ the size of `u32` is smaller than the size of `i64` | note: required by a bound in `is_transmutable` --> $DIR/numbers.rs:14:14 @@ -722,7 +722,7 @@ error[E0277]: `u32` cannot be safely transmuted into `f64` --> $DIR/numbers.rs:118:40 | LL | assert::is_transmutable::< u32, f64>(); - | ^^^ The size of `u32` is smaller than the size of `f64` + | ^^^ the size of `u32` is smaller than the size of `f64` | note: required by a bound in `is_transmutable` --> $DIR/numbers.rs:14:14 @@ -737,7 +737,7 @@ error[E0277]: `u32` cannot be safely transmuted into `u128` --> $DIR/numbers.rs:119:39 | LL | assert::is_transmutable::< u32, u128>(); - | ^^^^ The size of `u32` is smaller than the size of `u128` + | ^^^^ the size of `u32` is smaller than the size of `u128` | note: required by a bound in `is_transmutable` --> $DIR/numbers.rs:14:14 @@ -752,7 +752,7 @@ error[E0277]: `u32` cannot be safely transmuted into `i128` --> $DIR/numbers.rs:120:39 | LL | assert::is_transmutable::< u32, i128>(); - | ^^^^ The size of `u32` is smaller than the size of `i128` + | ^^^^ the size of `u32` is smaller than the size of `i128` | note: required by a bound in `is_transmutable` --> $DIR/numbers.rs:14:14 @@ -767,7 +767,7 @@ error[E0277]: `u64` cannot be safely transmuted into `u128` --> $DIR/numbers.rs:122:39 | LL | assert::is_transmutable::< u64, u128>(); - | ^^^^ The size of `u64` is smaller than the size of `u128` + | ^^^^ the size of `u64` is smaller than the size of `u128` | note: required by a bound in `is_transmutable` --> $DIR/numbers.rs:14:14 @@ -782,7 +782,7 @@ error[E0277]: `u64` cannot be safely transmuted into `i128` --> $DIR/numbers.rs:123:39 | LL | assert::is_transmutable::< u64, i128>(); - | ^^^^ The size of `u64` is smaller than the size of `i128` + | ^^^^ the size of `u64` is smaller than the size of `i128` | note: required by a bound in `is_transmutable` --> $DIR/numbers.rs:14:14 @@ -797,7 +797,7 @@ error[E0277]: `i64` cannot be safely transmuted into `u128` --> $DIR/numbers.rs:125:39 | LL | assert::is_transmutable::< i64, u128>(); - | ^^^^ The size of `i64` is smaller than the size of `u128` + | ^^^^ the size of `i64` is smaller than the size of `u128` | note: required by a bound in `is_transmutable` --> $DIR/numbers.rs:14:14 @@ -812,7 +812,7 @@ error[E0277]: `i64` cannot be safely transmuted into `i128` --> $DIR/numbers.rs:126:39 | LL | assert::is_transmutable::< i64, i128>(); - | ^^^^ The size of `i64` is smaller than the size of `i128` + | ^^^^ the size of `i64` is smaller than the size of `i128` | note: required by a bound in `is_transmutable` --> $DIR/numbers.rs:14:14 @@ -827,7 +827,7 @@ error[E0277]: `f64` cannot be safely transmuted into `u128` --> $DIR/numbers.rs:128:39 | LL | assert::is_transmutable::< f64, u128>(); - | ^^^^ The size of `f64` is smaller than the size of `u128` + | ^^^^ the size of `f64` is smaller than the size of `u128` | note: required by a bound in `is_transmutable` --> $DIR/numbers.rs:14:14 @@ -842,7 +842,7 @@ error[E0277]: `f64` cannot be safely transmuted into `i128` --> $DIR/numbers.rs:129:39 | LL | assert::is_transmutable::< f64, i128>(); - | ^^^^ The size of `f64` is smaller than the size of `i128` + | ^^^^ the size of `f64` is smaller than the size of `i128` | note: required by a bound in `is_transmutable` --> $DIR/numbers.rs:14:14 diff --git a/tests/ui/transmutability/primitives/unit.current.stderr b/tests/ui/transmutability/primitives/unit.current.stderr index b2831dbf842..52b708d680e 100644 --- a/tests/ui/transmutability/primitives/unit.current.stderr +++ b/tests/ui/transmutability/primitives/unit.current.stderr @@ -2,7 +2,7 @@ error[E0277]: `()` cannot be safely transmuted into `u8` --> $DIR/unit.rs:31:35 | LL | assert::is_transmutable::<(), u8>(); - | ^^ The size of `()` is smaller than the size of `u8` + | ^^ the size of `()` is smaller than the size of `u8` | note: required by a bound in `is_transmutable` --> $DIR/unit.rs:16:14 diff --git a/tests/ui/transmutability/primitives/unit.next.stderr b/tests/ui/transmutability/primitives/unit.next.stderr index b2831dbf842..52b708d680e 100644 --- a/tests/ui/transmutability/primitives/unit.next.stderr +++ b/tests/ui/transmutability/primitives/unit.next.stderr @@ -2,7 +2,7 @@ error[E0277]: `()` cannot be safely transmuted into `u8` --> $DIR/unit.rs:31:35 | LL | assert::is_transmutable::<(), u8>(); - | ^^ The size of `()` is smaller than the size of `u8` + | ^^ the size of `()` is smaller than the size of `u8` | note: required by a bound in `is_transmutable` --> $DIR/unit.rs:16:14 diff --git a/tests/ui/transmutability/references/recursive-wrapper-types-bit-incompatible.stderr b/tests/ui/transmutability/references/recursive-wrapper-types-bit-incompatible.stderr index 305fca30939..2b7cab1660d 100644 --- a/tests/ui/transmutability/references/recursive-wrapper-types-bit-incompatible.stderr +++ b/tests/ui/transmutability/references/recursive-wrapper-types-bit-incompatible.stderr @@ -2,7 +2,7 @@ error[E0277]: `B` cannot be safely transmuted into `A` --> $DIR/recursive-wrapper-types-bit-incompatible.rs:23:49 | LL | assert::is_maybe_transmutable::<&'static B, &'static A>(); - | ^^^^^^^^^^ At least one value of `B` isn't a bit-valid value of `A` + | ^^^^^^^^^^ at least one value of `B` isn't a bit-valid value of `A` | note: required by a bound in `is_maybe_transmutable` --> $DIR/recursive-wrapper-types-bit-incompatible.rs:9:14 diff --git a/tests/ui/transmutability/references/reject_extension.rs b/tests/ui/transmutability/references/reject_extension.rs new file mode 100644 index 00000000000..161da5772e8 --- /dev/null +++ b/tests/ui/transmutability/references/reject_extension.rs @@ -0,0 +1,49 @@ +//@ check-fail + +//! Reject extensions behind references. + +#![crate_type = "lib"] +#![feature(transmutability)] + +mod assert { + use std::mem::{Assume, BikeshedIntrinsicFrom}; + + pub fn is_transmutable<Src, Dst>() + where + Dst: BikeshedIntrinsicFrom< + Src, + { + Assume { + alignment: true, + lifetimes: true, + safety: true, + validity: true, + } + }, + >, + { + } +} + +#[repr(C, packed)] +struct Packed<T>(T); + +fn reject_extension() { + #[repr(C, align(2))] + struct Two(u8); + + #[repr(C, align(4))] + struct Four(u8); + + // These two types differ in the number of trailing padding bytes they have. + type Src = Packed<Two>; + type Dst = Packed<Four>; + + const _: () = { + use std::mem::size_of; + assert!(size_of::<Src>() == 2); + assert!(size_of::<Dst>() == 4); + }; + + assert::is_transmutable::<&Src, &Dst>(); //~ ERROR cannot be safely transmuted +} diff --git a/tests/ui/transmutability/references/reject_extension.stderr b/tests/ui/transmutability/references/reject_extension.stderr new file mode 100644 index 00000000000..88dd0313e3c --- /dev/null +++ b/tests/ui/transmutability/references/reject_extension.stderr @@ -0,0 +1,25 @@ +error[E0277]: `&Packed<Two>` cannot be safely transmuted into `&Packed<Four>` + --> $DIR/reject_extension.rs:48:37 + | +LL | assert::is_transmutable::<&Src, &Dst>(); + | ^^^^ the referent size of `&Packed<Two>` (2 bytes) is smaller than that of `&Packed<Four>` (4 bytes) + | +note: required by a bound in `is_transmutable` + --> $DIR/reject_extension.rs:13:14 + | +LL | pub fn is_transmutable<Src, Dst>() + | --------------- required by a bound in this function +LL | where +LL | Dst: BikeshedIntrinsicFrom< + | ______________^ +LL | | Src, +LL | | { +LL | | Assume { +... | +LL | | }, +LL | | >, + | |_________^ required by this bound in `is_transmutable` + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/transmutability/references/unit-to-u8.stderr b/tests/ui/transmutability/references/unit-to-u8.stderr index e2eb50442ca..5d73dfdc8eb 100644 --- a/tests/ui/transmutability/references/unit-to-u8.stderr +++ b/tests/ui/transmutability/references/unit-to-u8.stderr @@ -1,8 +1,8 @@ -error[E0277]: `Unit` cannot be safely transmuted into `u8` +error[E0277]: `&Unit` cannot be safely transmuted into `&u8` --> $DIR/unit-to-u8.rs:22:52 | LL | assert::is_maybe_transmutable::<&'static Unit, &'static u8>(); - | ^^^^^^^^^^^ The size of `Unit` is smaller than the size of `u8` + | ^^^^^^^^^^^ the referent size of `&Unit` (0 bytes) is smaller than that of `&u8` (1 bytes) | note: required by a bound in `is_maybe_transmutable` --> $DIR/unit-to-u8.rs:9:14 diff --git a/tests/ui/transmutability/region-infer.stderr b/tests/ui/transmutability/region-infer.stderr index 5497af2429e..03c46823838 100644 --- a/tests/ui/transmutability/region-infer.stderr +++ b/tests/ui/transmutability/region-infer.stderr @@ -2,7 +2,7 @@ error[E0277]: `()` cannot be safely transmuted into `W<'_>` --> $DIR/region-infer.rs:18:5 | LL | test(); - | ^^^^^^ The size of `()` is smaller than the size of `W<'_>` + | ^^^^^^ the size of `()` is smaller than the size of `W<'_>` | note: required by a bound in `test` --> $DIR/region-infer.rs:10:12 diff --git a/tests/ui/transmutability/structs/repr/should_require_well_defined_layout.stderr b/tests/ui/transmutability/structs/repr/should_require_well_defined_layout.stderr index 924422de538..77788f72c21 100644 --- a/tests/ui/transmutability/structs/repr/should_require_well_defined_layout.stderr +++ b/tests/ui/transmutability/structs/repr/should_require_well_defined_layout.stderr @@ -2,7 +2,7 @@ error[E0277]: `should_reject_repr_rust::unit::repr_rust` cannot be safely transm --> $DIR/should_require_well_defined_layout.rs:27:52 | LL | assert::is_maybe_transmutable::<repr_rust, ()>(); - | ^^ `should_reject_repr_rust::unit::repr_rust` does not have a well-specified layout + | ^^ analyzing the transmutability of `should_reject_repr_rust::unit::repr_rust` is not yet supported. | note: required by a bound in `is_maybe_transmutable` --> $DIR/should_require_well_defined_layout.rs:12:14 @@ -24,7 +24,7 @@ error[E0277]: `u128` cannot be safely transmuted into `should_reject_repr_rust:: --> $DIR/should_require_well_defined_layout.rs:28:47 | LL | assert::is_maybe_transmutable::<u128, repr_rust>(); - | ^^^^^^^^^ `should_reject_repr_rust::unit::repr_rust` does not have a well-specified layout + | ^^^^^^^^^ analyzing the transmutability of `should_reject_repr_rust::unit::repr_rust` is not yet supported. | note: required by a bound in `is_maybe_transmutable` --> $DIR/should_require_well_defined_layout.rs:12:14 @@ -46,7 +46,7 @@ error[E0277]: `should_reject_repr_rust::tuple::repr_rust` cannot be safely trans --> $DIR/should_require_well_defined_layout.rs:33:52 | LL | assert::is_maybe_transmutable::<repr_rust, ()>(); - | ^^ `should_reject_repr_rust::tuple::repr_rust` does not have a well-specified layout + | ^^ analyzing the transmutability of `should_reject_repr_rust::tuple::repr_rust` is not yet supported. | note: required by a bound in `is_maybe_transmutable` --> $DIR/should_require_well_defined_layout.rs:12:14 @@ -68,7 +68,7 @@ error[E0277]: `u128` cannot be safely transmuted into `should_reject_repr_rust:: --> $DIR/should_require_well_defined_layout.rs:34:47 | LL | assert::is_maybe_transmutable::<u128, repr_rust>(); - | ^^^^^^^^^ `should_reject_repr_rust::tuple::repr_rust` does not have a well-specified layout + | ^^^^^^^^^ analyzing the transmutability of `should_reject_repr_rust::tuple::repr_rust` is not yet supported. | note: required by a bound in `is_maybe_transmutable` --> $DIR/should_require_well_defined_layout.rs:12:14 @@ -90,7 +90,7 @@ error[E0277]: `should_reject_repr_rust::braces::repr_rust` cannot be safely tran --> $DIR/should_require_well_defined_layout.rs:39:52 | LL | assert::is_maybe_transmutable::<repr_rust, ()>(); - | ^^ `should_reject_repr_rust::braces::repr_rust` does not have a well-specified layout + | ^^ analyzing the transmutability of `should_reject_repr_rust::braces::repr_rust` is not yet supported. | note: required by a bound in `is_maybe_transmutable` --> $DIR/should_require_well_defined_layout.rs:12:14 @@ -112,7 +112,7 @@ error[E0277]: `u128` cannot be safely transmuted into `should_reject_repr_rust:: --> $DIR/should_require_well_defined_layout.rs:40:47 | LL | assert::is_maybe_transmutable::<u128, repr_rust>(); - | ^^^^^^^^^ `should_reject_repr_rust::braces::repr_rust` does not have a well-specified layout + | ^^^^^^^^^ analyzing the transmutability of `should_reject_repr_rust::braces::repr_rust` is not yet supported. | note: required by a bound in `is_maybe_transmutable` --> $DIR/should_require_well_defined_layout.rs:12:14 @@ -134,7 +134,7 @@ error[E0277]: `aligned::repr_rust` cannot be safely transmuted into `()` --> $DIR/should_require_well_defined_layout.rs:45:52 | LL | assert::is_maybe_transmutable::<repr_rust, ()>(); - | ^^ `aligned::repr_rust` does not have a well-specified layout + | ^^ analyzing the transmutability of `aligned::repr_rust` is not yet supported. | note: required by a bound in `is_maybe_transmutable` --> $DIR/should_require_well_defined_layout.rs:12:14 @@ -156,7 +156,7 @@ error[E0277]: `u128` cannot be safely transmuted into `aligned::repr_rust` --> $DIR/should_require_well_defined_layout.rs:46:47 | LL | assert::is_maybe_transmutable::<u128, repr_rust>(); - | ^^^^^^^^^ `aligned::repr_rust` does not have a well-specified layout + | ^^^^^^^^^ analyzing the transmutability of `aligned::repr_rust` is not yet supported. | note: required by a bound in `is_maybe_transmutable` --> $DIR/should_require_well_defined_layout.rs:12:14 @@ -178,7 +178,7 @@ error[E0277]: `packed::repr_rust` cannot be safely transmuted into `()` --> $DIR/should_require_well_defined_layout.rs:51:52 | LL | assert::is_maybe_transmutable::<repr_rust, ()>(); - | ^^ `packed::repr_rust` does not have a well-specified layout + | ^^ analyzing the transmutability of `packed::repr_rust` is not yet supported. | note: required by a bound in `is_maybe_transmutable` --> $DIR/should_require_well_defined_layout.rs:12:14 @@ -200,7 +200,7 @@ error[E0277]: `u128` cannot be safely transmuted into `packed::repr_rust` --> $DIR/should_require_well_defined_layout.rs:52:47 | LL | assert::is_maybe_transmutable::<u128, repr_rust>(); - | ^^^^^^^^^ `packed::repr_rust` does not have a well-specified layout + | ^^^^^^^^^ analyzing the transmutability of `packed::repr_rust` is not yet supported. | note: required by a bound in `is_maybe_transmutable` --> $DIR/should_require_well_defined_layout.rs:12:14 @@ -222,7 +222,7 @@ error[E0277]: `nested::repr_c` cannot be safely transmuted into `()` --> $DIR/should_require_well_defined_layout.rs:58:49 | LL | assert::is_maybe_transmutable::<repr_c, ()>(); - | ^^ `nested::repr_c` does not have a well-specified layout + | ^^ analyzing the transmutability of `nested::repr_c` is not yet supported. | note: required by a bound in `is_maybe_transmutable` --> $DIR/should_require_well_defined_layout.rs:12:14 @@ -244,7 +244,7 @@ error[E0277]: `u128` cannot be safely transmuted into `nested::repr_c` --> $DIR/should_require_well_defined_layout.rs:59:47 | LL | assert::is_maybe_transmutable::<u128, repr_c>(); - | ^^^^^^ `nested::repr_c` does not have a well-specified layout + | ^^^^^^ analyzing the transmutability of `nested::repr_c` is not yet supported. | note: required by a bound in `is_maybe_transmutable` --> $DIR/should_require_well_defined_layout.rs:12:14 diff --git a/tests/ui/transmutability/transmute-padding-ice.stderr b/tests/ui/transmutability/transmute-padding-ice.stderr index c48a5cd80ce..4c121d463c6 100644 --- a/tests/ui/transmutability/transmute-padding-ice.stderr +++ b/tests/ui/transmutability/transmute-padding-ice.stderr @@ -2,7 +2,7 @@ error[E0277]: `B` cannot be safely transmuted into `A` --> $DIR/transmute-padding-ice.rs:25:40 | LL | assert::is_maybe_transmutable::<B, A>(); - | ^ The size of `B` is smaller than the size of `A` + | ^ the size of `B` is smaller than the size of `A` | note: required by a bound in `is_maybe_transmutable` --> $DIR/transmute-padding-ice.rs:10:14 diff --git a/tests/ui/transmutability/unions/repr/should_require_well_defined_layout.stderr b/tests/ui/transmutability/unions/repr/should_require_well_defined_layout.stderr index ee0e8a66434..bec07f13103 100644 --- a/tests/ui/transmutability/unions/repr/should_require_well_defined_layout.stderr +++ b/tests/ui/transmutability/unions/repr/should_require_well_defined_layout.stderr @@ -2,7 +2,7 @@ error[E0277]: `should_reject_repr_rust::repr_rust` cannot be safely transmuted i --> $DIR/should_require_well_defined_layout.rs:29:48 | LL | assert::is_maybe_transmutable::<repr_rust, ()>(); - | ^^ `should_reject_repr_rust::repr_rust` does not have a well-specified layout + | ^^ analyzing the transmutability of `should_reject_repr_rust::repr_rust` is not yet supported. | note: required by a bound in `is_maybe_transmutable` --> $DIR/should_require_well_defined_layout.rs:12:14 @@ -24,7 +24,7 @@ error[E0277]: `u128` cannot be safely transmuted into `should_reject_repr_rust:: --> $DIR/should_require_well_defined_layout.rs:30:43 | LL | assert::is_maybe_transmutable::<u128, repr_rust>(); - | ^^^^^^^^^ `should_reject_repr_rust::repr_rust` does not have a well-specified layout + | ^^^^^^^^^ analyzing the transmutability of `should_reject_repr_rust::repr_rust` is not yet supported. | note: required by a bound in `is_maybe_transmutable` --> $DIR/should_require_well_defined_layout.rs:12:14 diff --git a/tests/ui/transmutability/unions/should_pad_variants.stderr b/tests/ui/transmutability/unions/should_pad_variants.stderr index 13b4c8053ad..da4294bdbce 100644 --- a/tests/ui/transmutability/unions/should_pad_variants.stderr +++ b/tests/ui/transmutability/unions/should_pad_variants.stderr @@ -2,7 +2,7 @@ error[E0277]: `Src` cannot be safely transmuted into `Dst` --> $DIR/should_pad_variants.rs:43:36 | LL | assert::is_transmutable::<Src, Dst>(); - | ^^^ The size of `Src` is smaller than the size of `Dst` + | ^^^ the size of `Src` is smaller than the size of `Dst` | note: required by a bound in `is_transmutable` --> $DIR/should_pad_variants.rs:13:14 diff --git a/tests/ui/transmutability/unions/should_reject_contraction.stderr b/tests/ui/transmutability/unions/should_reject_contraction.stderr index a3e387a0f84..20eaa3a6b09 100644 --- a/tests/ui/transmutability/unions/should_reject_contraction.stderr +++ b/tests/ui/transmutability/unions/should_reject_contraction.stderr @@ -2,7 +2,7 @@ error[E0277]: `Superset` cannot be safely transmuted into `Subset` --> $DIR/should_reject_contraction.rs:34:41 | LL | assert::is_transmutable::<Superset, Subset>(); - | ^^^^^^ At least one value of `Superset` isn't a bit-valid value of `Subset` + | ^^^^^^ at least one value of `Superset` isn't a bit-valid value of `Subset` | note: required by a bound in `is_transmutable` --> $DIR/should_reject_contraction.rs:12:14 diff --git a/tests/ui/transmutability/unions/should_reject_disjoint.stderr b/tests/ui/transmutability/unions/should_reject_disjoint.stderr index 447ab6d9de7..ea47797c970 100644 --- a/tests/ui/transmutability/unions/should_reject_disjoint.stderr +++ b/tests/ui/transmutability/unions/should_reject_disjoint.stderr @@ -2,7 +2,7 @@ error[E0277]: `A` cannot be safely transmuted into `B` --> $DIR/should_reject_disjoint.rs:32:40 | LL | assert::is_maybe_transmutable::<A, B>(); - | ^ At least one value of `A` isn't a bit-valid value of `B` + | ^ at least one value of `A` isn't a bit-valid value of `B` | note: required by a bound in `is_maybe_transmutable` --> $DIR/should_reject_disjoint.rs:12:14 @@ -17,7 +17,7 @@ error[E0277]: `B` cannot be safely transmuted into `A` --> $DIR/should_reject_disjoint.rs:33:40 | LL | assert::is_maybe_transmutable::<B, A>(); - | ^ At least one value of `B` isn't a bit-valid value of `A` + | ^ at least one value of `B` isn't a bit-valid value of `A` | note: required by a bound in `is_maybe_transmutable` --> $DIR/should_reject_disjoint.rs:12:14 diff --git a/tests/ui/transmutability/unions/should_reject_intersecting.stderr b/tests/ui/transmutability/unions/should_reject_intersecting.stderr index f0763bc8be7..79dec659d9d 100644 --- a/tests/ui/transmutability/unions/should_reject_intersecting.stderr +++ b/tests/ui/transmutability/unions/should_reject_intersecting.stderr @@ -2,7 +2,7 @@ error[E0277]: `A` cannot be safely transmuted into `B` --> $DIR/should_reject_intersecting.rs:35:34 | LL | assert::is_transmutable::<A, B>(); - | ^ At least one value of `A` isn't a bit-valid value of `B` + | ^ at least one value of `A` isn't a bit-valid value of `B` | note: required by a bound in `is_transmutable` --> $DIR/should_reject_intersecting.rs:13:14 @@ -17,7 +17,7 @@ error[E0277]: `B` cannot be safely transmuted into `A` --> $DIR/should_reject_intersecting.rs:36:34 | LL | assert::is_transmutable::<B, A>(); - | ^ At least one value of `B` isn't a bit-valid value of `A` + | ^ at least one value of `B` isn't a bit-valid value of `A` | note: required by a bound in `is_transmutable` --> $DIR/should_reject_intersecting.rs:13:14 diff --git a/tests/ui/type-alias-impl-trait/in-where-clause.rs b/tests/ui/type-alias-impl-trait/in-where-clause.rs index 0ad6e7a6f60..7c0de39c7c9 100644 --- a/tests/ui/type-alias-impl-trait/in-where-clause.rs +++ b/tests/ui/type-alias-impl-trait/in-where-clause.rs @@ -1,5 +1,5 @@ //! We evaluate `1 + 2` with `Reveal::All` during typeck, causing -//! us to to get the concrete type of `Bar` while computing it. +//! us to get the concrete type of `Bar` while computing it. //! This again requires type checking `foo`. #![feature(type_alias_impl_trait)] type Bar = impl Sized; diff --git a/tests/ui/typeck/ice-self-mismatch-const-generics.rs b/tests/ui/typeck/ice-self-mismatch-const-generics.rs new file mode 100644 index 00000000000..43f435ba4cf --- /dev/null +++ b/tests/ui/typeck/ice-self-mismatch-const-generics.rs @@ -0,0 +1,25 @@ +// Checks that the following does not ICE when constructing type mismatch diagnostic involving +// `Self` and const generics. +// Issue: <https://github.com/rust-lang/rust/issues/122467> + +pub struct GenericStruct<const N: usize, T> { + thing: T, +} + +impl<T> GenericStruct<0, T> { + pub fn new(thing: T) -> GenericStruct<1, T> { + Self { thing } + //~^ ERROR mismatched types + } +} + +pub struct GenericStruct2<const M: usize, T>(T); + +impl<T> GenericStruct2<0, T> { + pub fn new(thing: T) -> GenericStruct2<1, T> { + Self { 0: thing } + //~^ ERROR mismatched types + } +} + +fn main() {} diff --git a/tests/ui/typeck/ice-self-mismatch-const-generics.stderr b/tests/ui/typeck/ice-self-mismatch-const-generics.stderr new file mode 100644 index 00000000000..c502ea4565f --- /dev/null +++ b/tests/ui/typeck/ice-self-mismatch-const-generics.stderr @@ -0,0 +1,37 @@ +error[E0308]: mismatched types + --> $DIR/ice-self-mismatch-const-generics.rs:11:9 + | +LL | impl<T> GenericStruct<0, T> { + | ------------------- this is the type of the `Self` literal +LL | pub fn new(thing: T) -> GenericStruct<1, T> { + | ------------------- expected `GenericStruct<1, T>` because of return type +LL | Self { thing } + | ^^^^^^^^^^^^^^ expected `1`, found `0` + | + = note: expected struct `GenericStruct<_, 1>` + found struct `GenericStruct<_, 0>` +help: use the type name directly + | +LL | GenericStruct::<1, T> { thing } + | ~~~~~~~~~~~~~~~~~~~~~ + +error[E0308]: mismatched types + --> $DIR/ice-self-mismatch-const-generics.rs:20:9 + | +LL | impl<T> GenericStruct2<0, T> { + | -------------------- this is the type of the `Self` literal +LL | pub fn new(thing: T) -> GenericStruct2<1, T> { + | -------------------- expected `GenericStruct2<1, T>` because of return type +LL | Self { 0: thing } + | ^^^^^^^^^^^^^^^^^ expected `1`, found `0` + | + = note: expected struct `GenericStruct2<_, 1>` + found struct `GenericStruct2<_, 0>` +help: use the type name directly + | +LL | GenericStruct2::<1, T> { 0: thing } + | ~~~~~~~~~~~~~~~~~~~~~~ + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/typeck/mismatched-map-under-self.stderr b/tests/ui/typeck/mismatched-map-under-self.stderr index 13678b4b827..322bf349f92 100644 --- a/tests/ui/typeck/mismatched-map-under-self.stderr +++ b/tests/ui/typeck/mismatched-map-under-self.stderr @@ -27,7 +27,7 @@ LL | self.map(Insertable::values).unwrap_or_default() | required by a bound introduced by this call | = note: expected function signature `fn(T) -> _` - found function signature `for<'a> fn(&'a _) -> _` + found function signature `fn(&_) -> _` note: required by a bound in `Option::<T>::map` --> $SRC_DIR/core/src/option.rs:LL:COL help: consider wrapping the function in a closure diff --git a/tests/ui/unop-move-semantics.stderr b/tests/ui/unop-move-semantics.stderr index b6de7976ac9..187dd66b2fe 100644 --- a/tests/ui/unop-move-semantics.stderr +++ b/tests/ui/unop-move-semantics.stderr @@ -9,7 +9,7 @@ LL | LL | x.clone(); | ^ value borrowed here after move | -note: calling this operator moves the left-hand side +note: calling this operator moves the value --> $SRC_DIR/core/src/ops/bit.rs:LL:COL help: consider cloning the value if the performance cost is acceptable | @@ -57,7 +57,7 @@ LL | !*m; | |move occurs because `*m` has type `T`, which does not implement the `Copy` trait | `*m` moved due to usage in operator | -note: calling this operator moves the left-hand side +note: calling this operator moves the value --> $SRC_DIR/core/src/ops/bit.rs:LL:COL error[E0507]: cannot move out of `*n` which is behind a shared reference |
