diff options
Diffstat (limited to 'tests')
284 files changed, 4298 insertions, 939 deletions
diff --git a/tests/assembly/asm/aarch64-modifiers.rs b/tests/assembly/asm/aarch64-modifiers.rs index ffba06ae47b..b7ef1d77ea0 100644 --- a/tests/assembly/asm/aarch64-modifiers.rs +++ b/tests/assembly/asm/aarch64-modifiers.rs @@ -1,5 +1,5 @@ //@ assembly-output: emit-asm -//@ compile-flags: -O +//@ compile-flags: -O -C panic=abort //@ compile-flags: --target aarch64-unknown-linux-gnu //@ needs-llvm-components: aarch64 diff --git a/tests/assembly/asm/arm-modifiers.rs b/tests/assembly/asm/arm-modifiers.rs index fa2e75eb35b..0674e169d72 100644 --- a/tests/assembly/asm/arm-modifiers.rs +++ b/tests/assembly/asm/arm-modifiers.rs @@ -1,5 +1,5 @@ //@ assembly-output: emit-asm -//@ compile-flags: -O +//@ compile-flags: -O -C panic=abort //@ compile-flags: --target armv7-unknown-linux-gnueabihf //@ compile-flags: -C target-feature=+neon //@ needs-llvm-components: arm diff --git a/tests/assembly/asm/x86-modifiers.rs b/tests/assembly/asm/x86-modifiers.rs index 1a92585298d..c5e393b1056 100644 --- a/tests/assembly/asm/x86-modifiers.rs +++ b/tests/assembly/asm/x86-modifiers.rs @@ -1,6 +1,6 @@ //@ revisions: x86_64 i686 //@ assembly-output: emit-asm -//@ compile-flags: -O +//@ compile-flags: -O -C panic=abort //@[x86_64] compile-flags: --target x86_64-unknown-linux-gnu //@[x86_64] needs-llvm-components: x86 //@[i686] compile-flags: --target i686-unknown-linux-gnu diff --git a/tests/assembly/simd-bitmask.rs b/tests/assembly/simd-bitmask.rs index 8264a706852..cd22ca06706 100644 --- a/tests/assembly/simd-bitmask.rs +++ b/tests/assembly/simd-bitmask.rs @@ -11,7 +11,7 @@ //@ [aarch64] needs-llvm-components: aarch64 //@ [aarch64] min-llvm-version: 18.0 //@ assembly-output: emit-asm -//@ compile-flags: --crate-type=lib -O +//@ compile-flags: --crate-type=lib -O -C panic=abort #![feature(no_core, lang_items, repr_simd, intrinsics)] #![no_core] diff --git a/tests/assembly/simd-intrinsic-gather.rs b/tests/assembly/simd-intrinsic-gather.rs index ef6b597c25f..83015f05ab3 100644 --- a/tests/assembly/simd-intrinsic-gather.rs +++ b/tests/assembly/simd-intrinsic-gather.rs @@ -4,7 +4,7 @@ //@ [x86-avx512] needs-llvm-components: x86 //@ [x86-avx512] min-llvm-version: 18.0 //@ assembly-output: emit-asm -//@ compile-flags: --crate-type=lib -O +//@ compile-flags: --crate-type=lib -O -C panic=abort #![feature(no_core, lang_items, repr_simd, intrinsics)] #![no_core] diff --git a/tests/assembly/simd-intrinsic-mask-load.rs b/tests/assembly/simd-intrinsic-mask-load.rs index 49d231c45f8..d537c143d36 100644 --- a/tests/assembly/simd-intrinsic-mask-load.rs +++ b/tests/assembly/simd-intrinsic-mask-load.rs @@ -6,7 +6,7 @@ //@ [x86-avx512] compile-flags: -C target-feature=+avx512f,+avx512vl,+avx512bw,+avx512dq //@ [x86-avx512] needs-llvm-components: x86 //@ assembly-output: emit-asm -//@ compile-flags: --crate-type=lib -O +//@ compile-flags: --crate-type=lib -O -C panic=abort #![feature(no_core, lang_items, repr_simd, intrinsics)] #![no_core] diff --git a/tests/assembly/simd-intrinsic-mask-reduce.rs b/tests/assembly/simd-intrinsic-mask-reduce.rs index 72c3f6376e8..dd4dbaeda76 100644 --- a/tests/assembly/simd-intrinsic-mask-reduce.rs +++ b/tests/assembly/simd-intrinsic-mask-reduce.rs @@ -8,7 +8,7 @@ //@ [aarch64] needs-llvm-components: aarch64 //@ [aarch64] min-llvm-version: 18.0 //@ assembly-output: emit-asm -//@ compile-flags: --crate-type=lib -O +//@ compile-flags: --crate-type=lib -O -C panic=abort #![feature(no_core, lang_items, repr_simd, intrinsics)] #![no_core] diff --git a/tests/assembly/simd-intrinsic-mask-store.rs b/tests/assembly/simd-intrinsic-mask-store.rs index a6611e1c23d..5d4c00c3823 100644 --- a/tests/assembly/simd-intrinsic-mask-store.rs +++ b/tests/assembly/simd-intrinsic-mask-store.rs @@ -6,7 +6,7 @@ //@ [x86-avx512] compile-flags: -C target-feature=+avx512f,+avx512vl,+avx512bw,+avx512dq //@ [x86-avx512] needs-llvm-components: x86 //@ assembly-output: emit-asm -//@ compile-flags: --crate-type=lib -O +//@ compile-flags: --crate-type=lib -O -C panic=abort #![feature(no_core, lang_items, repr_simd, intrinsics)] #![no_core] diff --git a/tests/assembly/simd-intrinsic-scatter.rs b/tests/assembly/simd-intrinsic-scatter.rs index 6ffefb0801a..55095e4cb68 100644 --- a/tests/assembly/simd-intrinsic-scatter.rs +++ b/tests/assembly/simd-intrinsic-scatter.rs @@ -4,7 +4,7 @@ //@ [x86-avx512] needs-llvm-components: x86 //@ [x86-avx512] min-llvm-version: 18.0 //@ assembly-output: emit-asm -//@ compile-flags: --crate-type=lib -O +//@ compile-flags: --crate-type=lib -O -C panic=abort #![feature(no_core, lang_items, repr_simd, intrinsics)] #![no_core] diff --git a/tests/assembly/simd-intrinsic-select.rs b/tests/assembly/simd-intrinsic-select.rs index 3f36402e3d0..4dfc2f9ed1f 100644 --- a/tests/assembly/simd-intrinsic-select.rs +++ b/tests/assembly/simd-intrinsic-select.rs @@ -9,7 +9,7 @@ //@ [aarch64] needs-llvm-components: aarch64 //@ [aarch64] min-llvm-version: 18.0 //@ assembly-output: emit-asm -//@ compile-flags: --crate-type=lib -O +//@ compile-flags: --crate-type=lib -O -C panic=abort #![feature(no_core, lang_items, repr_simd, intrinsics)] #![no_core] diff --git a/tests/assembly/targets/targets-elf.rs b/tests/assembly/targets/targets-elf.rs index b069e667bf5..32cce3839dc 100644 --- a/tests/assembly/targets/targets-elf.rs +++ b/tests/assembly/targets/targets-elf.rs @@ -581,12 +581,21 @@ revisions: xtensa_esp32_none_elf [xtensa_esp32_none_elf] compile-flags: --target xtensa-esp32-none-elf [xtensa_esp32_none_elf] needs-llvm-components: xtensa + revisions: xtensa_esp32_espidf + [xtensa_esp32_espidf] compile-flags: --target xtensa-esp32s2-espidf + [xtensa_esp32_espidf] needs-llvm-components: xtensa revisions: xtensa_esp32s2_none_elf [xtensa_esp32s2_none_elf] compile-flags: --target xtensa-esp32s2-none-elf [xtensa_esp32s2_none_elf] needs-llvm-components: xtensa + revisions: xtensa_esp32s2_espidf + [xtensa_esp32s2_espidf] compile-flags: --target xtensa-esp32s2-espidf + [xtensa_esp32s2_espidf] needs-llvm-components: xtensa revisions: xtensa_esp32s3_none_elf [xtensa_esp32s3_none_elf] compile-flags: --target xtensa-esp32s3-none-elf [xtensa_esp32s3_none_elf] needs-llvm-components: xtensa + revisions: xtensa_esp32s3_espidf + [xtensa_esp32s3_espidf] compile-flags: --target xtensa-esp32s3-espidf + [xtensa_esp32s3_espidf] needs-llvm-components: xtensa */ // Sanity-check that each target can produce assembly code. diff --git a/tests/assembly/wasm_exceptions.rs b/tests/assembly/wasm_exceptions.rs index 7bdf7f1287c..f05ccfadc58 100644 --- a/tests/assembly/wasm_exceptions.rs +++ b/tests/assembly/wasm_exceptions.rs @@ -6,12 +6,12 @@ #![crate_type = "lib"] #![feature(core_intrinsics)] -#![feature(rustc_attrs)] -extern "C" { +extern "C-unwind" { fn may_panic(); +} - #[rustc_nounwind] +extern "C" { fn log_number(number: usize); } diff --git a/tests/codegen/align-byval-alignment-mismatch.rs b/tests/codegen/align-byval-alignment-mismatch.rs index 71f2dd42ec2..835cc7393e5 100644 --- a/tests/codegen/align-byval-alignment-mismatch.rs +++ b/tests/codegen/align-byval-alignment-mismatch.rs @@ -1,9 +1,9 @@ // ignore-tidy-linelength //@ revisions:i686-linux x86_64-linux -//@[i686-linux] compile-flags: --target i686-unknown-linux-gnu +//@[i686-linux] compile-flags: --target i686-unknown-linux-gnu -C panic=abort //@[i686-linux] needs-llvm-components: x86 -//@[x86_64-linux] compile-flags: --target x86_64-unknown-linux-gnu +//@[x86_64-linux] compile-flags: --target x86_64-unknown-linux-gnu -C panic=abort //@[x86_64-linux] needs-llvm-components: x86 // Tests that we correctly copy arguments into allocas when the alignment of the byval argument diff --git a/tests/codegen/array-repeat.rs b/tests/codegen/array-repeat.rs new file mode 100644 index 00000000000..b6f3b2e83d3 --- /dev/null +++ b/tests/codegen/array-repeat.rs @@ -0,0 +1,15 @@ +//@ compile-flags: -O + +#![crate_type = "lib"] +#![feature(array_repeat)] + +use std::array::repeat; + +// CHECK-LABEL: @byte_repeat +#[no_mangle] +fn byte_repeat(b: u8) -> [u8; 1024] { + // CHECK-NOT: alloca + // CHECK-NOT: store + // CHECK: memset + repeat(b) +} diff --git a/tests/codegen/avr/avr-func-addrspace.rs b/tests/codegen/avr/avr-func-addrspace.rs index 2d9efb52c7c..70834707564 100644 --- a/tests/codegen/avr/avr-func-addrspace.rs +++ b/tests/codegen/avr/avr-func-addrspace.rs @@ -1,4 +1,4 @@ -//@ compile-flags: -O --target=avr-unknown-gnu-atmega328 --crate-type=rlib +//@ compile-flags: -O --target=avr-unknown-gnu-atmega328 --crate-type=rlib -C panic=abort //@ needs-llvm-components: avr // This test validates that function pointers can be stored in global variables diff --git a/tests/codegen/catch-unwind.rs b/tests/codegen/catch-unwind.rs index 4e1f9a88e95..48ad486fa03 100644 --- a/tests/codegen/catch-unwind.rs +++ b/tests/codegen/catch-unwind.rs @@ -14,7 +14,6 @@ //@ ignore-loongarch64 FIXME #![crate_type = "lib"] -#![feature(c_unwind)] extern "C" { fn bar(); diff --git a/tests/codegen/cffi/c-variadic.rs b/tests/codegen/cffi/c-variadic.rs index 914d1623ed2..140d2f37f46 100644 --- a/tests/codegen/cffi/c-variadic.rs +++ b/tests/codegen/cffi/c-variadic.rs @@ -4,7 +4,6 @@ #![crate_type = "lib"] #![feature(c_variadic)] -#![feature(c_unwind)] #![no_std] use core::ffi::VaList; diff --git a/tests/codegen/debuginfo-inline-callsite-location.rs b/tests/codegen/debuginfo-inline-callsite-location.rs index f690c9c0937..aee07b4eb8c 100644 --- a/tests/codegen/debuginfo-inline-callsite-location.rs +++ b/tests/codegen/debuginfo-inline-callsite-location.rs @@ -1,4 +1,4 @@ -//@ compile-flags: -g -O +//@ compile-flags: -g -O -C panic=abort // Check that each inline call site for the same function uses the same "sub-program" so that LLVM // can correctly merge the debug info if it merges the inlined code (e.g., for merging of tail diff --git a/tests/codegen/issues/issue-112509-slice-get-andthen-get.rs b/tests/codegen/issues/issue-112509-slice-get-andthen-get.rs index ae02c3fb79e..aee2edd8dfa 100644 --- a/tests/codegen/issues/issue-112509-slice-get-andthen-get.rs +++ b/tests/codegen/issues/issue-112509-slice-get-andthen-get.rs @@ -3,8 +3,12 @@ // CHECK-LABEL: @write_u8_variant_a // CHECK-NEXT: {{.*}}: -// CHECK-NEXT: getelementptr // CHECK-NEXT: icmp ugt +// CHECK-NEXT: getelementptr +// CHECK-NEXT: select i1 {{.+}} null +// CHECK-NEXT: insertvalue +// CHECK-NEXT: insertvalue +// CHECK-NEXT: ret #[no_mangle] pub fn write_u8_variant_a(bytes: &mut [u8], buf: u8, offset: usize) -> Option<&mut [u8]> { let buf = buf.to_le_bytes(); diff --git a/tests/codegen/riscv-abi/riscv64-lp64-lp64f-lp64d-abi.rs b/tests/codegen/riscv-abi/riscv64-lp64-lp64f-lp64d-abi.rs index 977749ad578..ed0af90aaaf 100644 --- a/tests/codegen/riscv-abi/riscv64-lp64-lp64f-lp64d-abi.rs +++ b/tests/codegen/riscv-abi/riscv64-lp64-lp64f-lp64d-abi.rs @@ -1,4 +1,4 @@ -//@ compile-flags: --target riscv64gc-unknown-linux-gnu -O -C no-prepopulate-passes +//@ compile-flags: --target riscv64gc-unknown-linux-gnu -O -C no-prepopulate-passes -C panic=abort //@ needs-llvm-components: riscv #![crate_type = "lib"] diff --git a/tests/codegen/unwind-abis/aapcs-unwind-abi.rs b/tests/codegen/unwind-abis/aapcs-unwind-abi.rs index 48c7ecf7824..0d9c7757883 100644 --- a/tests/codegen/unwind-abis/aapcs-unwind-abi.rs +++ b/tests/codegen/unwind-abis/aapcs-unwind-abi.rs @@ -1,7 +1,7 @@ //@ needs-llvm-components: arm //@ compile-flags: --target=armv7-unknown-linux-gnueabihf --crate-type=rlib -Cno-prepopulate-passes #![no_core] -#![feature(no_core, lang_items, c_unwind)] +#![feature(no_core, lang_items)] #[lang = "sized"] trait Sized {} diff --git a/tests/codegen/unwind-abis/c-unwind-abi-panic-abort.rs b/tests/codegen/unwind-abis/c-unwind-abi-panic-abort.rs index 8bb2122946f..8d2745ba2f7 100644 --- a/tests/codegen/unwind-abis/c-unwind-abi-panic-abort.rs +++ b/tests/codegen/unwind-abis/c-unwind-abi-panic-abort.rs @@ -4,7 +4,6 @@ // when the code is compiled with `panic=abort`. #![crate_type = "lib"] -#![feature(c_unwind)] // CHECK: @rust_item_that_can_unwind() unnamed_addr [[ATTR0:#[0-9]+]] #[no_mangle] diff --git a/tests/codegen/unwind-abis/c-unwind-abi.rs b/tests/codegen/unwind-abis/c-unwind-abi.rs index 99763943a6a..46c08b5fc4f 100644 --- a/tests/codegen/unwind-abis/c-unwind-abi.rs +++ b/tests/codegen/unwind-abis/c-unwind-abi.rs @@ -6,7 +6,6 @@ // to prevent LLVM from inferring the attribute. #![crate_type = "lib"] -#![feature(c_unwind)] // CHECK: @rust_item_that_cannot_unwind() unnamed_addr #0 { #[no_mangle] diff --git a/tests/codegen/unwind-abis/cdecl-unwind-abi.rs b/tests/codegen/unwind-abis/cdecl-unwind-abi.rs index 78dbb55b35a..8e643d6ce49 100644 --- a/tests/codegen/unwind-abis/cdecl-unwind-abi.rs +++ b/tests/codegen/unwind-abis/cdecl-unwind-abi.rs @@ -6,7 +6,6 @@ // disable optimizations above to prevent LLVM from inferring the attribute. #![crate_type = "lib"] -#![feature(c_unwind)] // CHECK: @rust_item_that_cannot_unwind() unnamed_addr #0 { #[no_mangle] diff --git a/tests/codegen/unwind-abis/fastcall-unwind-abi.rs b/tests/codegen/unwind-abis/fastcall-unwind-abi.rs index 3cbeaf51d96..4c7b2856e2e 100644 --- a/tests/codegen/unwind-abis/fastcall-unwind-abi.rs +++ b/tests/codegen/unwind-abis/fastcall-unwind-abi.rs @@ -1,7 +1,7 @@ //@ needs-llvm-components: x86 //@ compile-flags: --target=i686-pc-windows-msvc --crate-type=rlib -Cno-prepopulate-passes #![no_core] -#![feature(no_core, lang_items, c_unwind)] +#![feature(no_core, lang_items)] #[lang = "sized"] trait Sized {} diff --git a/tests/codegen/unwind-abis/nounwind-on-stable-panic-unwind.rs b/tests/codegen/unwind-abis/nounwind-on-stable-panic-unwind.rs deleted file mode 100644 index a7f7f2fb77f..00000000000 --- a/tests/codegen/unwind-abis/nounwind-on-stable-panic-unwind.rs +++ /dev/null @@ -1,17 +0,0 @@ -//@ compile-flags: -C opt-level=0 -//@ needs-unwind - -#![crate_type = "lib"] - -// We disable optimizations to prevent LLVM from inferring the attribute. - -extern "C" { - fn bar(); -} - -// CHECK-NOT: Function Attrs:{{.*}}nounwind -pub unsafe extern "C" fn foo() { - bar(); -} - -// Note that this test will get removed when `C-unwind` is fully stabilized diff --git a/tests/codegen/unwind-abis/nounwind.rs b/tests/codegen/unwind-abis/nounwind.rs index 80bf8d67091..e40ed48ca73 100644 --- a/tests/codegen/unwind-abis/nounwind.rs +++ b/tests/codegen/unwind-abis/nounwind.rs @@ -2,7 +2,6 @@ //@ needs-unwind #![crate_type = "lib"] -#![feature(c_unwind)] // We disable optimizations to prevent LLVM from inferring the attribute. diff --git a/tests/codegen/unwind-abis/stdcall-unwind-abi.rs b/tests/codegen/unwind-abis/stdcall-unwind-abi.rs index ffb235cd116..ffc11d1faef 100644 --- a/tests/codegen/unwind-abis/stdcall-unwind-abi.rs +++ b/tests/codegen/unwind-abis/stdcall-unwind-abi.rs @@ -1,7 +1,7 @@ //@ needs-llvm-components: x86 //@ compile-flags: --target=i686-pc-windows-msvc --crate-type=rlib -Cno-prepopulate-passes #![no_core] -#![feature(no_core, lang_items, c_unwind)] +#![feature(no_core, lang_items)] #[lang = "sized"] trait Sized {} diff --git a/tests/codegen/unwind-abis/system-unwind-abi.rs b/tests/codegen/unwind-abis/system-unwind-abi.rs index 1dd0e9bbbec..5f910248346 100644 --- a/tests/codegen/unwind-abis/system-unwind-abi.rs +++ b/tests/codegen/unwind-abis/system-unwind-abi.rs @@ -6,7 +6,6 @@ // optimizations above to prevent LLVM from inferring the attribute. #![crate_type = "lib"] -#![feature(c_unwind)] // CHECK: @rust_item_that_cannot_unwind() unnamed_addr #0 { #[no_mangle] diff --git a/tests/codegen/unwind-abis/sysv64-unwind-abi.rs b/tests/codegen/unwind-abis/sysv64-unwind-abi.rs index 9824009dc55..c869ca7e2b8 100644 --- a/tests/codegen/unwind-abis/sysv64-unwind-abi.rs +++ b/tests/codegen/unwind-abis/sysv64-unwind-abi.rs @@ -1,7 +1,7 @@ //@ needs-llvm-components: x86 //@ compile-flags: --target=x86_64-unknown-linux-gnu --crate-type=rlib -Cno-prepopulate-passes #![no_core] -#![feature(no_core, lang_items, c_unwind)] +#![feature(no_core, lang_items)] #[lang = "sized"] trait Sized {} diff --git a/tests/codegen/unwind-abis/thiscall-unwind-abi.rs b/tests/codegen/unwind-abis/thiscall-unwind-abi.rs index a96f4d5a350..19b23ee47ba 100644 --- a/tests/codegen/unwind-abis/thiscall-unwind-abi.rs +++ b/tests/codegen/unwind-abis/thiscall-unwind-abi.rs @@ -1,7 +1,7 @@ //@ needs-llvm-components: x86 //@ compile-flags: --target=i686-pc-windows-msvc --crate-type=rlib -Cno-prepopulate-passes #![no_core] -#![feature(no_core, lang_items, c_unwind)] +#![feature(no_core, lang_items)] #[lang = "sized"] trait Sized {} diff --git a/tests/codegen/unwind-abis/vectorcall-unwind-abi.rs b/tests/codegen/unwind-abis/vectorcall-unwind-abi.rs index 9929e3e3703..b420f67ca9b 100644 --- a/tests/codegen/unwind-abis/vectorcall-unwind-abi.rs +++ b/tests/codegen/unwind-abis/vectorcall-unwind-abi.rs @@ -1,7 +1,7 @@ //@ needs-llvm-components: x86 //@ compile-flags: --target=i686-pc-windows-msvc --crate-type=rlib -Cno-prepopulate-passes #![no_core] -#![feature(no_core, lang_items, c_unwind, abi_vectorcall)] +#![feature(no_core, lang_items, abi_vectorcall)] #[lang = "sized"] trait Sized {} diff --git a/tests/codegen/unwind-abis/win64-unwind-abi.rs b/tests/codegen/unwind-abis/win64-unwind-abi.rs index a45a94f628d..2697d3cbcd6 100644 --- a/tests/codegen/unwind-abis/win64-unwind-abi.rs +++ b/tests/codegen/unwind-abis/win64-unwind-abi.rs @@ -1,7 +1,7 @@ //@ needs-llvm-components: x86 //@ compile-flags: --target=x86_64-unknown-linux-gnu --crate-type=rlib -Cno-prepopulate-passes #![no_core] -#![feature(no_core, lang_items, c_unwind)] +#![feature(no_core, lang_items)] #[lang = "sized"] trait Sized {} diff --git a/tests/codegen/unwind-and-panic-abort.rs b/tests/codegen/unwind-and-panic-abort.rs index 430502308cf..8efa140058a 100644 --- a/tests/codegen/unwind-and-panic-abort.rs +++ b/tests/codegen/unwind-and-panic-abort.rs @@ -1,7 +1,6 @@ //@ compile-flags: -C panic=abort #![crate_type = "lib"] -#![feature(c_unwind)] extern "C-unwind" { fn bar(); diff --git a/tests/codegen/unwind-extern-exports.rs b/tests/codegen/unwind-extern-exports.rs index ea59748b3bc..e692fd1a547 100644 --- a/tests/codegen/unwind-extern-exports.rs +++ b/tests/codegen/unwind-extern-exports.rs @@ -2,7 +2,6 @@ //@ needs-unwind #![crate_type = "lib"] -#![feature(c_unwind)] // Make sure these all do *not* get the attribute. // We disable optimizations to prevent LLVM from inferring the attribute. diff --git a/tests/codegen/unwind-extern-imports.rs b/tests/codegen/unwind-extern-imports.rs index 790e4def8b3..dfae8aae64a 100644 --- a/tests/codegen/unwind-extern-imports.rs +++ b/tests/codegen/unwind-extern-imports.rs @@ -2,7 +2,6 @@ //@ needs-unwind #![crate_type = "lib"] -#![feature(c_unwind)] extern "C" { // CHECK: Function Attrs:{{.*}}nounwind diff --git a/tests/codegen/wasm_exceptions.rs b/tests/codegen/wasm_exceptions.rs index 3910850e03a..719499dd8ea 100644 --- a/tests/codegen/wasm_exceptions.rs +++ b/tests/codegen/wasm_exceptions.rs @@ -3,12 +3,12 @@ #![crate_type = "lib"] #![feature(core_intrinsics)] -#![feature(rustc_attrs)] -extern "C" { +extern "C-unwind" { fn may_panic(); +} - #[rustc_nounwind] +extern "C" { fn log_number(number: usize); } diff --git a/tests/coverage/abort.cov-map b/tests/coverage/abort.cov-map index 5673fa98ca6..15156ec9811 100644 --- a/tests/coverage/abort.cov-map +++ b/tests/coverage/abort.cov-map @@ -1,5 +1,5 @@ Function name: abort::main -Raw bytes (89): 0x[01, 01, 0a, 01, 27, 05, 09, 03, 0d, 22, 11, 03, 0d, 03, 0d, 22, 15, 03, 0d, 03, 0d, 05, 09, 0d, 01, 0e, 01, 01, 1b, 03, 02, 0b, 00, 18, 22, 01, 0c, 00, 19, 11, 00, 1a, 02, 0a, 0e, 02, 0a, 00, 0b, 22, 02, 0c, 00, 19, 15, 00, 1a, 00, 31, 1a, 00, 31, 00, 32, 22, 04, 0c, 00, 19, 05, 00, 1a, 00, 31, 09, 00, 31, 00, 32, 27, 01, 09, 00, 17, 0d, 02, 05, 01, 02] +Raw bytes (89): 0x[01, 01, 0a, 01, 27, 05, 09, 03, 0d, 22, 11, 03, 0d, 03, 0d, 22, 15, 03, 0d, 03, 0d, 05, 09, 0d, 01, 0d, 01, 01, 1b, 03, 02, 0b, 00, 18, 22, 01, 0c, 00, 19, 11, 00, 1a, 02, 0a, 0e, 02, 0a, 00, 0b, 22, 02, 0c, 00, 19, 15, 00, 1a, 00, 31, 1a, 00, 31, 00, 32, 22, 04, 0c, 00, 19, 05, 00, 1a, 00, 31, 09, 00, 31, 00, 32, 27, 01, 09, 00, 17, 0d, 02, 05, 01, 02] Number of files: 1 - file 0 => global file 1 Number of expressions: 10 @@ -14,7 +14,7 @@ Number of expressions: 10 - expression 8 operands: lhs = Expression(0, Add), rhs = Counter(3) - expression 9 operands: lhs = Counter(1), rhs = Counter(2) Number of file 0 mappings: 13 -- Code(Counter(0)) at (prev + 14, 1) to (start + 1, 27) +- Code(Counter(0)) at (prev + 13, 1) to (start + 1, 27) - Code(Expression(0, Add)) at (prev + 2, 11) to (start + 0, 24) = (c0 + (c1 + c2)) - Code(Expression(8, Sub)) at (prev + 1, 12) to (start + 0, 25) @@ -36,13 +36,13 @@ Number of file 0 mappings: 13 - Code(Counter(3)) at (prev + 2, 5) to (start + 1, 2) Function name: abort::might_abort -Raw bytes (21): 0x[01, 01, 01, 01, 05, 03, 01, 04, 01, 01, 14, 05, 02, 09, 01, 24, 02, 02, 0c, 03, 02] +Raw bytes (21): 0x[01, 01, 01, 01, 05, 03, 01, 03, 01, 01, 14, 05, 02, 09, 01, 24, 02, 02, 0c, 03, 02] Number of files: 1 - file 0 => global file 1 Number of expressions: 1 - expression 0 operands: lhs = Counter(0), rhs = Counter(1) Number of file 0 mappings: 3 -- Code(Counter(0)) at (prev + 4, 1) to (start + 1, 20) +- Code(Counter(0)) at (prev + 3, 1) to (start + 1, 20) - Code(Counter(1)) at (prev + 2, 9) to (start + 1, 36) - Code(Expression(0, Sub)) at (prev + 2, 12) to (start + 3, 2) = (c0 - c1) diff --git a/tests/coverage/abort.coverage b/tests/coverage/abort.coverage index b658a656259..29e3ad5eda7 100644 --- a/tests/coverage/abort.coverage +++ b/tests/coverage/abort.coverage @@ -1,4 +1,3 @@ - LL| |#![feature(c_unwind)] LL| |#![allow(unused_assignments)] LL| | LL| 12|extern "C" fn might_abort(should_abort: bool) { diff --git a/tests/coverage/abort.rs b/tests/coverage/abort.rs index 649e8e52a49..6c06a3f9d87 100644 --- a/tests/coverage/abort.rs +++ b/tests/coverage/abort.rs @@ -1,4 +1,3 @@ -#![feature(c_unwind)] #![allow(unused_assignments)] extern "C" fn might_abort(should_abort: bool) { diff --git a/tests/coverage/closure_macro.cov-map b/tests/coverage/closure_macro.cov-map index 156947f4e21..21fad22f58f 100644 --- a/tests/coverage/closure_macro.cov-map +++ b/tests/coverage/closure_macro.cov-map @@ -22,19 +22,19 @@ Number of file 0 mappings: 5 - Code(Counter(0)) at (prev + 3, 1) to (start + 0, 2) Function name: closure_macro::main::{closure#0} -Raw bytes (35): 0x[01, 01, 03, 01, 05, 05, 0b, 09, 00, 05, 01, 10, 1c, 03, 21, 05, 04, 11, 01, 27, 02, 03, 11, 00, 16, 00, 00, 17, 00, 1e, 07, 02, 09, 00, 0a] +Raw bytes (35): 0x[01, 01, 03, 01, 05, 05, 0b, 09, 0d, 05, 01, 10, 1c, 03, 21, 05, 04, 11, 01, 27, 02, 03, 11, 00, 16, 0d, 00, 17, 00, 1e, 07, 02, 09, 00, 0a] Number of files: 1 - file 0 => global file 1 Number of expressions: 3 - expression 0 operands: lhs = Counter(0), rhs = Counter(1) - expression 1 operands: lhs = Counter(1), rhs = Expression(2, Add) -- expression 2 operands: lhs = Counter(2), rhs = Zero +- expression 2 operands: lhs = Counter(2), rhs = Counter(3) Number of file 0 mappings: 5 - Code(Counter(0)) at (prev + 16, 28) to (start + 3, 33) - Code(Counter(1)) at (prev + 4, 17) to (start + 1, 39) - Code(Expression(0, Sub)) at (prev + 3, 17) to (start + 0, 22) = (c0 - c1) -- Code(Zero) at (prev + 0, 23) to (start + 0, 30) +- Code(Counter(3)) at (prev + 0, 23) to (start + 0, 30) - Code(Expression(1, Add)) at (prev + 2, 9) to (start + 0, 10) - = (c1 + (c2 + Zero)) + = (c1 + (c2 + c3)) diff --git a/tests/coverage/closure_macro_async.cov-map b/tests/coverage/closure_macro_async.cov-map index 0f2b4e01748..f2efd550591 100644 --- a/tests/coverage/closure_macro_async.cov-map +++ b/tests/coverage/closure_macro_async.cov-map @@ -30,19 +30,19 @@ Number of file 0 mappings: 5 - Code(Counter(0)) at (prev + 3, 1) to (start + 0, 2) Function name: closure_macro_async::test::{closure#0}::{closure#0} -Raw bytes (35): 0x[01, 01, 03, 01, 05, 05, 0b, 09, 00, 05, 01, 12, 1c, 03, 21, 05, 04, 11, 01, 27, 02, 03, 11, 00, 16, 00, 00, 17, 00, 1e, 07, 02, 09, 00, 0a] +Raw bytes (35): 0x[01, 01, 03, 01, 05, 05, 0b, 09, 0d, 05, 01, 12, 1c, 03, 21, 05, 04, 11, 01, 27, 02, 03, 11, 00, 16, 0d, 00, 17, 00, 1e, 07, 02, 09, 00, 0a] Number of files: 1 - file 0 => global file 1 Number of expressions: 3 - expression 0 operands: lhs = Counter(0), rhs = Counter(1) - expression 1 operands: lhs = Counter(1), rhs = Expression(2, Add) -- expression 2 operands: lhs = Counter(2), rhs = Zero +- expression 2 operands: lhs = Counter(2), rhs = Counter(3) Number of file 0 mappings: 5 - Code(Counter(0)) at (prev + 18, 28) to (start + 3, 33) - Code(Counter(1)) at (prev + 4, 17) to (start + 1, 39) - Code(Expression(0, Sub)) at (prev + 3, 17) to (start + 0, 22) = (c0 - c1) -- Code(Zero) at (prev + 0, 23) to (start + 0, 30) +- Code(Counter(3)) at (prev + 0, 23) to (start + 0, 30) - Code(Expression(1, Add)) at (prev + 2, 9) to (start + 0, 10) - = (c1 + (c2 + Zero)) + = (c1 + (c2 + c3)) diff --git a/tests/coverage/mcdc_non_control_flow.cov-map b/tests/coverage/mcdc_non_control_flow.cov-map new file mode 100644 index 00000000000..937c36e1f16 --- /dev/null +++ b/tests/coverage/mcdc_non_control_flow.cov-map @@ -0,0 +1,204 @@ +Function name: mcdc_non_control_flow::assign_3 +Raw bytes (89): 0x[01, 01, 09, 05, 07, 0b, 11, 09, 0d, 01, 05, 01, 05, 22, 11, 01, 05, 22, 11, 01, 05, 0a, 01, 16, 01, 00, 28, 03, 01, 09, 00, 0a, 01, 00, 0d, 00, 0e, 28, 00, 03, 00, 0d, 00, 18, 30, 05, 22, 01, 00, 02, 00, 0d, 00, 0e, 22, 00, 12, 00, 13, 30, 1e, 11, 02, 03, 00, 00, 12, 00, 13, 1e, 00, 17, 00, 18, 30, 09, 0d, 03, 00, 00, 00, 17, 00, 18, 03, 01, 05, 01, 02] +Number of files: 1 +- file 0 => global file 1 +Number of expressions: 9 +- expression 0 operands: lhs = Counter(1), rhs = Expression(1, Add) +- expression 1 operands: lhs = Expression(2, Add), rhs = Counter(4) +- expression 2 operands: lhs = Counter(2), rhs = Counter(3) +- expression 3 operands: lhs = Counter(0), rhs = Counter(1) +- expression 4 operands: lhs = Counter(0), rhs = Counter(1) +- expression 5 operands: lhs = Expression(8, Sub), rhs = Counter(4) +- expression 6 operands: lhs = Counter(0), rhs = Counter(1) +- expression 7 operands: lhs = Expression(8, Sub), rhs = Counter(4) +- expression 8 operands: lhs = Counter(0), rhs = Counter(1) +Number of file 0 mappings: 10 +- Code(Counter(0)) at (prev + 22, 1) to (start + 0, 40) +- Code(Expression(0, Add)) at (prev + 1, 9) to (start + 0, 10) + = (c1 + ((c2 + c3) + c4)) +- Code(Counter(0)) at (prev + 0, 13) to (start + 0, 14) +- MCDCDecision { bitmap_idx: 0, conditions_num: 3 } at (prev + 0, 13) to (start + 0, 24) +- MCDCBranch { true: Counter(1), false: Expression(8, Sub), condition_id: 1, true_next_id: 0, false_next_id: 2 } at (prev + 0, 13) to (start + 0, 14) + true = c1 + false = (c0 - c1) +- Code(Expression(8, Sub)) at (prev + 0, 18) to (start + 0, 19) + = (c0 - c1) +- MCDCBranch { true: Expression(7, Sub), false: Counter(4), condition_id: 2, true_next_id: 3, false_next_id: 0 } at (prev + 0, 18) to (start + 0, 19) + true = ((c0 - c1) - c4) + false = c4 +- Code(Expression(7, Sub)) at (prev + 0, 23) to (start + 0, 24) + = ((c0 - c1) - c4) +- MCDCBranch { true: Counter(2), false: Counter(3), condition_id: 3, true_next_id: 0, false_next_id: 0 } at (prev + 0, 23) to (start + 0, 24) + true = c2 + false = c3 +- Code(Expression(0, Add)) at (prev + 1, 5) to (start + 1, 2) + = (c1 + ((c2 + c3) + c4)) + +Function name: mcdc_non_control_flow::assign_3_bis +Raw bytes (85): 0x[01, 01, 07, 07, 11, 09, 0d, 01, 05, 05, 09, 16, 1a, 05, 09, 01, 05, 0a, 01, 1b, 01, 00, 2c, 03, 01, 09, 00, 0a, 01, 00, 0d, 00, 0e, 28, 00, 03, 00, 0d, 00, 18, 30, 05, 1a, 01, 03, 02, 00, 0d, 00, 0e, 05, 00, 12, 00, 13, 30, 09, 16, 03, 00, 02, 00, 12, 00, 13, 13, 00, 17, 00, 18, 30, 0d, 11, 02, 00, 00, 00, 17, 00, 18, 03, 01, 05, 01, 02] +Number of files: 1 +- file 0 => global file 1 +Number of expressions: 7 +- expression 0 operands: lhs = Expression(1, Add), rhs = Counter(4) +- expression 1 operands: lhs = Counter(2), rhs = Counter(3) +- expression 2 operands: lhs = Counter(0), rhs = Counter(1) +- expression 3 operands: lhs = Counter(1), rhs = Counter(2) +- expression 4 operands: lhs = Expression(5, Sub), rhs = Expression(6, Sub) +- expression 5 operands: lhs = Counter(1), rhs = Counter(2) +- expression 6 operands: lhs = Counter(0), rhs = Counter(1) +Number of file 0 mappings: 10 +- Code(Counter(0)) at (prev + 27, 1) to (start + 0, 44) +- Code(Expression(0, Add)) at (prev + 1, 9) to (start + 0, 10) + = ((c2 + c3) + c4) +- Code(Counter(0)) at (prev + 0, 13) to (start + 0, 14) +- MCDCDecision { bitmap_idx: 0, conditions_num: 3 } at (prev + 0, 13) to (start + 0, 24) +- MCDCBranch { true: Counter(1), false: Expression(6, Sub), condition_id: 1, true_next_id: 3, false_next_id: 2 } at (prev + 0, 13) to (start + 0, 14) + true = c1 + false = (c0 - c1) +- Code(Counter(1)) at (prev + 0, 18) to (start + 0, 19) +- MCDCBranch { true: Counter(2), false: Expression(5, Sub), condition_id: 3, true_next_id: 0, false_next_id: 2 } at (prev + 0, 18) to (start + 0, 19) + true = c2 + false = (c1 - c2) +- Code(Expression(4, Add)) at (prev + 0, 23) to (start + 0, 24) + = ((c1 - c2) + (c0 - c1)) +- MCDCBranch { true: Counter(3), false: Counter(4), condition_id: 2, true_next_id: 0, false_next_id: 0 } at (prev + 0, 23) to (start + 0, 24) + true = c3 + false = c4 +- Code(Expression(0, Add)) at (prev + 1, 5) to (start + 1, 2) + = ((c2 + c3) + c4) + +Function name: mcdc_non_control_flow::assign_and +Raw bytes (64): 0x[01, 01, 04, 07, 0e, 09, 0d, 01, 05, 01, 05, 08, 01, 0c, 01, 00, 21, 03, 01, 09, 00, 0a, 01, 00, 0d, 00, 0e, 28, 00, 02, 00, 0d, 00, 13, 30, 05, 0e, 01, 02, 00, 00, 0d, 00, 0e, 05, 00, 12, 00, 13, 30, 09, 0d, 02, 00, 00, 00, 12, 00, 13, 03, 01, 05, 01, 02] +Number of files: 1 +- file 0 => global file 1 +Number of expressions: 4 +- expression 0 operands: lhs = Expression(1, Add), rhs = Expression(3, Sub) +- expression 1 operands: lhs = Counter(2), rhs = Counter(3) +- expression 2 operands: lhs = Counter(0), rhs = Counter(1) +- expression 3 operands: lhs = Counter(0), rhs = Counter(1) +Number of file 0 mappings: 8 +- Code(Counter(0)) at (prev + 12, 1) to (start + 0, 33) +- Code(Expression(0, Add)) at (prev + 1, 9) to (start + 0, 10) + = ((c2 + c3) + (c0 - c1)) +- Code(Counter(0)) at (prev + 0, 13) to (start + 0, 14) +- MCDCDecision { bitmap_idx: 0, conditions_num: 2 } at (prev + 0, 13) to (start + 0, 19) +- MCDCBranch { true: Counter(1), false: Expression(3, Sub), condition_id: 1, true_next_id: 2, false_next_id: 0 } at (prev + 0, 13) to (start + 0, 14) + true = c1 + false = (c0 - c1) +- Code(Counter(1)) at (prev + 0, 18) to (start + 0, 19) +- MCDCBranch { true: Counter(2), false: Counter(3), condition_id: 2, true_next_id: 0, false_next_id: 0 } at (prev + 0, 18) to (start + 0, 19) + true = c2 + false = c3 +- Code(Expression(0, Add)) at (prev + 1, 5) to (start + 1, 2) + = ((c2 + c3) + (c0 - c1)) + +Function name: mcdc_non_control_flow::assign_or +Raw bytes (64): 0x[01, 01, 04, 07, 0d, 05, 09, 01, 05, 01, 05, 08, 01, 11, 01, 00, 20, 03, 01, 09, 00, 0a, 01, 00, 0d, 00, 0e, 28, 00, 02, 00, 0d, 00, 13, 30, 05, 0e, 01, 00, 02, 00, 0d, 00, 0e, 0e, 00, 12, 00, 13, 30, 09, 0d, 02, 00, 00, 00, 12, 00, 13, 03, 01, 05, 01, 02] +Number of files: 1 +- file 0 => global file 1 +Number of expressions: 4 +- expression 0 operands: lhs = Expression(1, Add), rhs = Counter(3) +- expression 1 operands: lhs = Counter(1), rhs = Counter(2) +- expression 2 operands: lhs = Counter(0), rhs = Counter(1) +- expression 3 operands: lhs = Counter(0), rhs = Counter(1) +Number of file 0 mappings: 8 +- Code(Counter(0)) at (prev + 17, 1) to (start + 0, 32) +- Code(Expression(0, Add)) at (prev + 1, 9) to (start + 0, 10) + = ((c1 + c2) + c3) +- Code(Counter(0)) at (prev + 0, 13) to (start + 0, 14) +- MCDCDecision { bitmap_idx: 0, conditions_num: 2 } at (prev + 0, 13) to (start + 0, 19) +- MCDCBranch { true: Counter(1), false: Expression(3, Sub), condition_id: 1, true_next_id: 0, false_next_id: 2 } at (prev + 0, 13) to (start + 0, 14) + true = c1 + false = (c0 - c1) +- Code(Expression(3, Sub)) at (prev + 0, 18) to (start + 0, 19) + = (c0 - c1) +- MCDCBranch { true: Counter(2), false: Counter(3), condition_id: 2, true_next_id: 0, false_next_id: 0 } at (prev + 0, 18) to (start + 0, 19) + true = c2 + false = c3 +- Code(Expression(0, Add)) at (prev + 1, 5) to (start + 1, 2) + = ((c1 + c2) + c3) + +Function name: mcdc_non_control_flow::foo +Raw bytes (9): 0x[01, 01, 00, 01, 01, 25, 01, 02, 02] +Number of files: 1 +- file 0 => global file 1 +Number of expressions: 0 +Number of file 0 mappings: 1 +- Code(Counter(0)) at (prev + 37, 1) to (start + 2, 2) + +Function name: mcdc_non_control_flow::func_call +Raw bytes (52): 0x[01, 01, 03, 01, 05, 0b, 02, 09, 0d, 06, 01, 29, 01, 01, 0a, 28, 00, 02, 01, 09, 00, 0f, 30, 05, 02, 01, 02, 00, 00, 09, 00, 0a, 05, 00, 0e, 00, 0f, 30, 09, 0d, 02, 00, 00, 00, 0e, 00, 0f, 07, 01, 01, 00, 02] +Number of files: 1 +- file 0 => global file 1 +Number of expressions: 3 +- expression 0 operands: lhs = Counter(0), rhs = Counter(1) +- expression 1 operands: lhs = Expression(2, Add), rhs = Expression(0, Sub) +- expression 2 operands: lhs = Counter(2), rhs = Counter(3) +Number of file 0 mappings: 6 +- Code(Counter(0)) at (prev + 41, 1) to (start + 1, 10) +- MCDCDecision { bitmap_idx: 0, conditions_num: 2 } at (prev + 1, 9) to (start + 0, 15) +- MCDCBranch { true: Counter(1), false: Expression(0, Sub), condition_id: 1, true_next_id: 2, false_next_id: 0 } at (prev + 0, 9) to (start + 0, 10) + true = c1 + false = (c0 - c1) +- Code(Counter(1)) at (prev + 0, 14) to (start + 0, 15) +- MCDCBranch { true: Counter(2), false: Counter(3), condition_id: 2, true_next_id: 0, false_next_id: 0 } at (prev + 0, 14) to (start + 0, 15) + true = c2 + false = c3 +- Code(Expression(1, Add)) at (prev + 1, 1) to (start + 0, 2) + = ((c2 + c3) + (c0 - c1)) + +Function name: mcdc_non_control_flow::right_comb_tree +Raw bytes (139): 0x[01, 01, 13, 07, 1a, 0b, 19, 0f, 15, 13, 11, 09, 0d, 01, 05, 01, 05, 05, 19, 05, 19, 4a, 15, 05, 19, 4a, 15, 05, 19, 46, 11, 4a, 15, 05, 19, 46, 11, 4a, 15, 05, 19, 0e, 01, 20, 01, 00, 41, 03, 01, 09, 00, 0a, 01, 00, 0d, 00, 0e, 28, 00, 05, 00, 0d, 00, 2a, 30, 05, 1a, 01, 02, 00, 00, 0d, 00, 0e, 05, 00, 13, 00, 14, 30, 4a, 19, 02, 03, 00, 00, 13, 00, 14, 4a, 00, 19, 00, 1a, 30, 46, 15, 03, 04, 00, 00, 19, 00, 1a, 46, 00, 1f, 00, 20, 30, 42, 11, 04, 05, 00, 00, 1f, 00, 20, 42, 00, 24, 00, 27, 30, 09, 0d, 05, 00, 00, 00, 24, 00, 27, 03, 01, 05, 01, 02] +Number of files: 1 +- file 0 => global file 1 +Number of expressions: 19 +- expression 0 operands: lhs = Expression(1, Add), rhs = Expression(6, Sub) +- expression 1 operands: lhs = Expression(2, Add), rhs = Counter(6) +- expression 2 operands: lhs = Expression(3, Add), rhs = Counter(5) +- expression 3 operands: lhs = Expression(4, Add), rhs = Counter(4) +- expression 4 operands: lhs = Counter(2), rhs = Counter(3) +- expression 5 operands: lhs = Counter(0), rhs = Counter(1) +- expression 6 operands: lhs = Counter(0), rhs = Counter(1) +- expression 7 operands: lhs = Counter(1), rhs = Counter(6) +- expression 8 operands: lhs = Counter(1), rhs = Counter(6) +- expression 9 operands: lhs = Expression(18, Sub), rhs = Counter(5) +- expression 10 operands: lhs = Counter(1), rhs = Counter(6) +- expression 11 operands: lhs = Expression(18, Sub), rhs = Counter(5) +- expression 12 operands: lhs = Counter(1), rhs = Counter(6) +- expression 13 operands: lhs = Expression(17, Sub), rhs = Counter(4) +- expression 14 operands: lhs = Expression(18, Sub), rhs = Counter(5) +- expression 15 operands: lhs = Counter(1), rhs = Counter(6) +- expression 16 operands: lhs = Expression(17, Sub), rhs = Counter(4) +- expression 17 operands: lhs = Expression(18, Sub), rhs = Counter(5) +- expression 18 operands: lhs = Counter(1), rhs = Counter(6) +Number of file 0 mappings: 14 +- Code(Counter(0)) at (prev + 32, 1) to (start + 0, 65) +- Code(Expression(0, Add)) at (prev + 1, 9) to (start + 0, 10) + = (((((c2 + c3) + c4) + c5) + c6) + (c0 - c1)) +- Code(Counter(0)) at (prev + 0, 13) to (start + 0, 14) +- MCDCDecision { bitmap_idx: 0, conditions_num: 5 } at (prev + 0, 13) to (start + 0, 42) +- MCDCBranch { true: Counter(1), false: Expression(6, Sub), condition_id: 1, true_next_id: 2, false_next_id: 0 } at (prev + 0, 13) to (start + 0, 14) + true = c1 + false = (c0 - c1) +- Code(Counter(1)) at (prev + 0, 19) to (start + 0, 20) +- MCDCBranch { true: Expression(18, Sub), false: Counter(6), condition_id: 2, true_next_id: 3, false_next_id: 0 } at (prev + 0, 19) to (start + 0, 20) + true = (c1 - c6) + false = c6 +- Code(Expression(18, Sub)) at (prev + 0, 25) to (start + 0, 26) + = (c1 - c6) +- MCDCBranch { true: Expression(17, Sub), false: Counter(5), condition_id: 3, true_next_id: 4, false_next_id: 0 } at (prev + 0, 25) to (start + 0, 26) + true = ((c1 - c6) - c5) + false = c5 +- Code(Expression(17, Sub)) at (prev + 0, 31) to (start + 0, 32) + = ((c1 - c6) - c5) +- MCDCBranch { true: Expression(16, Sub), false: Counter(4), condition_id: 4, true_next_id: 5, false_next_id: 0 } at (prev + 0, 31) to (start + 0, 32) + true = (((c1 - c6) - c5) - c4) + false = c4 +- Code(Expression(16, Sub)) at (prev + 0, 36) to (start + 0, 39) + = (((c1 - c6) - c5) - c4) +- MCDCBranch { true: Counter(2), false: Counter(3), condition_id: 5, true_next_id: 0, false_next_id: 0 } at (prev + 0, 36) to (start + 0, 39) + true = c2 + false = c3 +- Code(Expression(0, Add)) at (prev + 1, 5) to (start + 1, 2) + = (((((c2 + c3) + c4) + c5) + c6) + (c0 - c1)) + diff --git a/tests/coverage/mcdc_non_control_flow.coverage b/tests/coverage/mcdc_non_control_flow.coverage new file mode 100644 index 00000000000..cd733885a98 --- /dev/null +++ b/tests/coverage/mcdc_non_control_flow.coverage @@ -0,0 +1,202 @@ + LL| |#![feature(coverage_attribute)] + LL| |//@ edition: 2021 + LL| |//@ min-llvm-version: 18 + LL| |//@ compile-flags: -Zcoverage-options=mcdc + LL| |//@ llvm-cov-flags: --show-mcdc + LL| | + LL| |// This test ensures that boolean expressions that are not inside control flow + LL| |// decisions are correctly instrumented. + LL| | + LL| |use core::hint::black_box; + LL| | + LL| 3|fn assign_and(a: bool, b: bool) { + LL| 3| let x = a && b; + ^2 + ------------------ + |---> MC/DC Decision Region (LL:13) to (LL:19) + | + | Number of Conditions: 2 + | Condition C1 --> (LL:13) + | Condition C2 --> (LL:18) + | + | Executed MC/DC Test Vectors: + | + | C1, C2 Result + | 1 { F, - = F } + | 2 { T, F = F } + | 3 { T, T = T } + | + | C1-Pair: covered: (1,3) + | C2-Pair: covered: (2,3) + | MC/DC Coverage for Decision: 100.00% + | + ------------------ + LL| 3| black_box(x); + LL| 3|} + LL| | + LL| 3|fn assign_or(a: bool, b: bool) { + LL| 3| let x = a || b; + ^1 + ------------------ + |---> MC/DC Decision Region (LL:13) to (LL:19) + | + | Number of Conditions: 2 + | Condition C1 --> (LL:13) + | Condition C2 --> (LL:18) + | + | Executed MC/DC Test Vectors: + | + | C1, C2 Result + | 1 { F, F = F } + | 2 { T, - = T } + | + | C1-Pair: covered: (1,2) + | C2-Pair: not covered + | MC/DC Coverage for Decision: 50.00% + | + ------------------ + LL| 3| black_box(x); + LL| 3|} + LL| | + LL| 4|fn assign_3(a: bool, b: bool, c: bool) { + LL| 4| let x = a || b && c; + ^2 ^1 + ------------------ + |---> MC/DC Decision Region (LL:13) to (LL:24) + | + | Number of Conditions: 3 + | Condition C1 --> (LL:13) + | Condition C2 --> (LL:18) + | Condition C3 --> (LL:23) + | + | Executed MC/DC Test Vectors: + | + | C1, C2, C3 Result + | 1 { F, F, - = F } + | 2 { T, -, - = T } + | 3 { F, T, T = T } + | + | C1-Pair: covered: (1,2) + | C2-Pair: covered: (1,3) + | C3-Pair: not covered + | MC/DC Coverage for Decision: 66.67% + | + ------------------ + LL| 4| black_box(x); + LL| 4|} + LL| | + LL| 4|fn assign_3_bis(a: bool, b: bool, c: bool) { + LL| 4| let x = a && b || c; + ^2 ^3 + ------------------ + |---> MC/DC Decision Region (LL:13) to (LL:24) + | + | Number of Conditions: 3 + | Condition C1 --> (LL:13) + | Condition C2 --> (LL:18) + | Condition C3 --> (LL:23) + | + | Executed MC/DC Test Vectors: + | + | C1, C2, C3 Result + | 1 { T, F, F = F } + | 2 { F, -, T = T } + | 3 { T, T, - = T } + | + | C1-Pair: not covered + | C2-Pair: covered: (1,3) + | C3-Pair: not covered + | MC/DC Coverage for Decision: 33.33% + | + ------------------ + LL| 4| black_box(x); + LL| 4|} + LL| | + LL| 3|fn right_comb_tree(a: bool, b: bool, c: bool, d: bool, e: bool) { + LL| 3| let x = a && (b && (c && (d && (e)))); + ^2 ^1 ^1 ^1 + ------------------ + |---> MC/DC Decision Region (LL:13) to (LL:42) + | + | Number of Conditions: 5 + | Condition C1 --> (LL:13) + | Condition C2 --> (LL:19) + | Condition C3 --> (LL:25) + | Condition C4 --> (LL:31) + | Condition C5 --> (LL:36) + | + | Executed MC/DC Test Vectors: + | + | C1, C2, C3, C4, C5 Result + | 1 { F, -, -, -, - = F } + | 2 { T, F, -, -, - = F } + | 3 { T, T, T, T, T = T } + | + | C1-Pair: covered: (1,3) + | C2-Pair: covered: (2,3) + | C3-Pair: not covered + | C4-Pair: not covered + | C5-Pair: not covered + | MC/DC Coverage for Decision: 40.00% + | + ------------------ + LL| 3| black_box(x); + LL| 3|} + LL| | + LL| 3|fn foo(a: bool) -> bool { + LL| 3| black_box(a) + LL| 3|} + LL| | + LL| 3|fn func_call(a: bool, b: bool) { + LL| 3| foo(a && b); + ^2 + ------------------ + |---> MC/DC Decision Region (LL:9) to (LL:15) + | + | Number of Conditions: 2 + | Condition C1 --> (LL:9) + | Condition C2 --> (LL:14) + | + | Executed MC/DC Test Vectors: + | + | C1, C2 Result + | 1 { F, - = F } + | 2 { T, F = F } + | 3 { T, T = T } + | + | C1-Pair: covered: (1,3) + | C2-Pair: covered: (2,3) + | MC/DC Coverage for Decision: 100.00% + | + ------------------ + LL| 3|} + LL| | + LL| |#[coverage(off)] + LL| |fn main() { + LL| | assign_and(true, false); + LL| | assign_and(true, true); + LL| | assign_and(false, false); + LL| | + LL| | assign_or(true, false); + LL| | assign_or(true, true); + LL| | assign_or(false, false); + LL| | + LL| | assign_3(true, false, false); + LL| | assign_3(true, true, false); + LL| | assign_3(false, false, true); + LL| | assign_3(false, true, true); + LL| | + LL| | assign_3_bis(true, false, false); + LL| | assign_3_bis(true, true, false); + LL| | assign_3_bis(false, false, true); + LL| | assign_3_bis(false, true, true); + LL| | + LL| | right_comb_tree(false, false, false, true, true); + LL| | right_comb_tree(true, false, false, true, true); + LL| | right_comb_tree(true, true, true, true, true); + LL| | + LL| | func_call(true, false); + LL| | func_call(true, true); + LL| | func_call(false, false); + LL| |} + diff --git a/tests/coverage/mcdc_non_control_flow.rs b/tests/coverage/mcdc_non_control_flow.rs new file mode 100644 index 00000000000..85c0a6c6ae5 --- /dev/null +++ b/tests/coverage/mcdc_non_control_flow.rs @@ -0,0 +1,72 @@ +#![feature(coverage_attribute)] +//@ edition: 2021 +//@ min-llvm-version: 18 +//@ compile-flags: -Zcoverage-options=mcdc +//@ llvm-cov-flags: --show-mcdc + +// This test ensures that boolean expressions that are not inside control flow +// decisions are correctly instrumented. + +use core::hint::black_box; + +fn assign_and(a: bool, b: bool) { + let x = a && b; + black_box(x); +} + +fn assign_or(a: bool, b: bool) { + let x = a || b; + black_box(x); +} + +fn assign_3(a: bool, b: bool, c: bool) { + let x = a || b && c; + black_box(x); +} + +fn assign_3_bis(a: bool, b: bool, c: bool) { + let x = a && b || c; + black_box(x); +} + +fn right_comb_tree(a: bool, b: bool, c: bool, d: bool, e: bool) { + let x = a && (b && (c && (d && (e)))); + black_box(x); +} + +fn foo(a: bool) -> bool { + black_box(a) +} + +fn func_call(a: bool, b: bool) { + foo(a && b); +} + +#[coverage(off)] +fn main() { + assign_and(true, false); + assign_and(true, true); + assign_and(false, false); + + assign_or(true, false); + assign_or(true, true); + assign_or(false, false); + + assign_3(true, false, false); + assign_3(true, true, false); + assign_3(false, false, true); + assign_3(false, true, true); + + assign_3_bis(true, false, false); + assign_3_bis(true, true, false); + assign_3_bis(false, false, true); + assign_3_bis(false, true, true); + + right_comb_tree(false, false, false, true, true); + right_comb_tree(true, false, false, true, true); + right_comb_tree(true, true, true, true, true); + + func_call(true, false); + func_call(true, true); + func_call(false, false); +} diff --git a/tests/crashes/122044.rs b/tests/crashes/122044.rs deleted file mode 100644 index 4c1d0de5719..00000000000 --- a/tests/crashes/122044.rs +++ /dev/null @@ -1,38 +0,0 @@ -//@ known-bug: #122044 -use std::hint::black_box; - -trait Func { - type Ret: Id; -} - -trait Id { - type Assoc; -} -impl Id for u32 {} -impl Id for u32 {} - -impl<F: FnOnce() -> R, R: Id> Func for F { - type Ret = R; -} - -fn bar() -> impl Copy + Id { - 0u32 -} - -struct Foo<T: Func> { - _func: T, - value: Option<<<T as Func>::Ret as Id>::Assoc>, -} - -fn main() { - let mut fn_def = black_box(Foo { - _func: bar, - value: None, - }); - let fn_ptr = black_box(Foo { - _func: bar as fn() -> _, - value: None, - }); - - fn_def.value = fn_ptr.value; -} diff --git a/tests/crashes/123255.rs b/tests/crashes/123255.rs deleted file mode 100644 index a94a2a0422e..00000000000 --- a/tests/crashes/123255.rs +++ /dev/null @@ -1,13 +0,0 @@ -//@ known-bug: rust-lang/rust#123255 -//@ edition:2021 -#![crate_type = "lib"] - -pub fn a() {} - -mod handlers { - pub struct C(&()); - pub fn c() -> impl Fn() -> C { - let a1 = (); - || C((crate::a(), a1).into()) - } -} diff --git a/tests/crashes/123893.rs b/tests/crashes/123893.rs index 137ae783511..05237d002b8 100644 --- a/tests/crashes/123893.rs +++ b/tests/crashes/123893.rs @@ -11,6 +11,7 @@ fn generic_impl<T>() { impl<T> MagicTrait for T { const IS_BIG: bool = true; } + more_cost(); if T::IS_BIG { big_impl::<i32>(); } @@ -18,3 +19,6 @@ fn generic_impl<T>() { #[inline(never)] fn big_impl<T>() {} + +#[inline(never)] +fn more_cost() {} diff --git a/tests/crashes/126521.rs b/tests/crashes/126521.rs deleted file mode 100644 index 0a025aabcf2..00000000000 --- a/tests/crashes/126521.rs +++ /dev/null @@ -1,11 +0,0 @@ -//@ known-bug: rust-lang/rust#126521 -macro_rules! foo { - ($val:ident) => { - true; - }; -} - -fn main() { - #[expect(semicolon_in_expressions_from_macros)] - let _ = foo!(x); -} diff --git a/tests/incremental/const-generics/issue-64087.rs b/tests/incremental/const-generics/issue-64087.rs index 97f212b3fbb..787f2af8aa3 100644 --- a/tests/incremental/const-generics/issue-64087.rs +++ b/tests/incremental/const-generics/issue-64087.rs @@ -6,4 +6,6 @@ fn combinator<T, const S: usize>() -> [T; S] {} fn main() { combinator().into_iter(); //[cfail1]~^ ERROR type annotations needed + //[cfail1]~| ERROR type annotations needed + //[cfail1]~| ERROR type annotations needed } diff --git a/tests/incremental/unrecoverable_query.rs b/tests/incremental/unrecoverable_query.rs new file mode 100644 index 00000000000..e17236bebd2 --- /dev/null +++ b/tests/incremental/unrecoverable_query.rs @@ -0,0 +1,40 @@ +// If it is impossible to find query arguments just from the hash +// compiler should treat the node as red + +// In this test prior to fixing compiler was having problems figuring out +// drop impl for T inside of m + +//@ revisions:cfail1 cfail2 +//@ compile-flags: --crate-type=lib +//@ build-pass + +pub trait P { + type A; +} + +struct S; + +impl P for S { + type A = C; +} + +struct T<D: P>(D::A, Z<D>); + +struct Z<D: P>(D::A, String); + +impl<D: P> T<D> { + pub fn i() -> Self { + loop {} + } +} + +enum C { + #[cfg(cfail1)] + Up(()), + #[cfg(cfail2)] + Lorry(()), +} + +pub fn m() { + T::<S>::i(); +} diff --git a/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.GVN.32bit.panic-abort.diff b/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.GVN.32bit.panic-abort.diff index ca445046279..06011f9d759 100644 --- a/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.GVN.32bit.panic-abort.diff +++ b/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.GVN.32bit.panic-abort.diff @@ -80,7 +80,7 @@ bb4: { StorageDead(_8); -- _11 = _6 as *const [bool; 0] (PointerCoercion(MutToConstPointer)); +- _11 = _6 as *const [bool; 0] (PtrToPtr); - _5 = NonNull::<[bool; 0]> { pointer: _11 }; + _11 = const {0x1 as *const [bool; 0]}; + _5 = const NonNull::<[bool; 0]> {{ pointer: {0x1 as *const [bool; 0]} }}; diff --git a/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.GVN.32bit.panic-unwind.diff b/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.GVN.32bit.panic-unwind.diff index 1f498c65fa7..eb4a3ffd91d 100644 --- a/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.GVN.32bit.panic-unwind.diff +++ b/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.GVN.32bit.panic-unwind.diff @@ -84,7 +84,7 @@ bb5: { StorageDead(_8); -- _11 = _6 as *const [bool; 0] (PointerCoercion(MutToConstPointer)); +- _11 = _6 as *const [bool; 0] (PtrToPtr); - _5 = NonNull::<[bool; 0]> { pointer: _11 }; + _11 = const {0x1 as *const [bool; 0]}; + _5 = const NonNull::<[bool; 0]> {{ pointer: {0x1 as *const [bool; 0]} }}; diff --git a/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.GVN.64bit.panic-abort.diff b/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.GVN.64bit.panic-abort.diff index da72e581496..a7cc243e548 100644 --- a/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.GVN.64bit.panic-abort.diff +++ b/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.GVN.64bit.panic-abort.diff @@ -80,7 +80,7 @@ bb4: { StorageDead(_8); -- _11 = _6 as *const [bool; 0] (PointerCoercion(MutToConstPointer)); +- _11 = _6 as *const [bool; 0] (PtrToPtr); - _5 = NonNull::<[bool; 0]> { pointer: _11 }; + _11 = const {0x1 as *const [bool; 0]}; + _5 = const NonNull::<[bool; 0]> {{ pointer: {0x1 as *const [bool; 0]} }}; diff --git a/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.GVN.64bit.panic-unwind.diff b/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.GVN.64bit.panic-unwind.diff index 920e66452e3..c905a48862c 100644 --- a/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.GVN.64bit.panic-unwind.diff +++ b/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.GVN.64bit.panic-unwind.diff @@ -84,7 +84,7 @@ bb5: { StorageDead(_8); -- _11 = _6 as *const [bool; 0] (PointerCoercion(MutToConstPointer)); +- _11 = _6 as *const [bool; 0] (PtrToPtr); - _5 = NonNull::<[bool; 0]> { pointer: _11 }; + _11 = const {0x1 as *const [bool; 0]}; + _5 = const NonNull::<[bool; 0]> {{ pointer: {0x1 as *const [bool; 0]} }}; diff --git a/tests/mir-opt/gvn.array_len.GVN.panic-abort.diff b/tests/mir-opt/gvn.array_len.GVN.panic-abort.diff new file mode 100644 index 00000000000..90654e05662 --- /dev/null +++ b/tests/mir-opt/gvn.array_len.GVN.panic-abort.diff @@ -0,0 +1,31 @@ +- // MIR for `array_len` before GVN ++ // MIR for `array_len` after GVN + + fn array_len(_1: &mut [i32; 42]) -> usize { + debug x => _1; + let mut _0: usize; + let _2: &[i32]; + let mut _3: &[i32; 42]; + let mut _4: *const [i32]; + scope 1 { + debug x => _2; + } + + bb0: { +- StorageLive(_2); ++ nop; + StorageLive(_3); + _3 = &(*_1); + _2 = move _3 as &[i32] (PointerCoercion(Unsize)); + StorageDead(_3); + StorageLive(_4); + _4 = &raw const (*_2); +- _0 = PtrMetadata(move _4); ++ _0 = const 42_usize; + StorageDead(_4); +- StorageDead(_2); ++ nop; + return; + } + } + diff --git a/tests/mir-opt/gvn.array_len.GVN.panic-unwind.diff b/tests/mir-opt/gvn.array_len.GVN.panic-unwind.diff new file mode 100644 index 00000000000..90654e05662 --- /dev/null +++ b/tests/mir-opt/gvn.array_len.GVN.panic-unwind.diff @@ -0,0 +1,31 @@ +- // MIR for `array_len` before GVN ++ // MIR for `array_len` after GVN + + fn array_len(_1: &mut [i32; 42]) -> usize { + debug x => _1; + let mut _0: usize; + let _2: &[i32]; + let mut _3: &[i32; 42]; + let mut _4: *const [i32]; + scope 1 { + debug x => _2; + } + + bb0: { +- StorageLive(_2); ++ nop; + StorageLive(_3); + _3 = &(*_1); + _2 = move _3 as &[i32] (PointerCoercion(Unsize)); + StorageDead(_3); + StorageLive(_4); + _4 = &raw const (*_2); +- _0 = PtrMetadata(move _4); ++ _0 = const 42_usize; + StorageDead(_4); +- StorageDead(_2); ++ nop; + return; + } + } + diff --git a/tests/mir-opt/gvn.fn_pointers.GVN.panic-abort.diff b/tests/mir-opt/gvn.fn_pointers.GVN.panic-abort.diff index 25d0e5ccf49..0c49e706c9e 100644 --- a/tests/mir-opt/gvn.fn_pointers.GVN.panic-abort.diff +++ b/tests/mir-opt/gvn.fn_pointers.GVN.panic-abort.diff @@ -8,10 +8,10 @@ let mut _3: fn(u8) -> u8; let _5: (); let mut _6: fn(u8) -> u8; - let mut _9: {closure@$DIR/gvn.rs:612:19: 612:21}; + let mut _9: {closure@$DIR/gvn.rs:614:19: 614:21}; let _10: (); let mut _11: fn(); - let mut _13: {closure@$DIR/gvn.rs:612:19: 612:21}; + let mut _13: {closure@$DIR/gvn.rs:614:19: 614:21}; let _14: (); let mut _15: fn(); scope 1 { @@ -19,7 +19,7 @@ let _4: fn(u8) -> u8; scope 2 { debug g => _4; - let _7: {closure@$DIR/gvn.rs:612:19: 612:21}; + let _7: {closure@$DIR/gvn.rs:614:19: 614:21}; scope 3 { debug closure => _7; let _8: fn(); @@ -62,16 +62,16 @@ StorageDead(_6); StorageDead(_5); - StorageLive(_7); -- _7 = {closure@$DIR/gvn.rs:612:19: 612:21}; +- _7 = {closure@$DIR/gvn.rs:614:19: 614:21}; - StorageLive(_8); + nop; -+ _7 = const ZeroSized: {closure@$DIR/gvn.rs:612:19: 612:21}; ++ _7 = const ZeroSized: {closure@$DIR/gvn.rs:614:19: 614:21}; + nop; StorageLive(_9); - _9 = _7; - _8 = move _9 as fn() (PointerCoercion(ClosureFnPointer(Safe))); -+ _9 = const ZeroSized: {closure@$DIR/gvn.rs:612:19: 612:21}; -+ _8 = const ZeroSized: {closure@$DIR/gvn.rs:612:19: 612:21} as fn() (PointerCoercion(ClosureFnPointer(Safe))); ++ _9 = const ZeroSized: {closure@$DIR/gvn.rs:614:19: 614:21}; ++ _8 = const ZeroSized: {closure@$DIR/gvn.rs:614:19: 614:21} as fn() (PointerCoercion(ClosureFnPointer(Safe))); StorageDead(_9); StorageLive(_10); StorageLive(_11); @@ -88,8 +88,8 @@ StorageLive(_13); - _13 = _7; - _12 = move _13 as fn() (PointerCoercion(ClosureFnPointer(Safe))); -+ _13 = const ZeroSized: {closure@$DIR/gvn.rs:612:19: 612:21}; -+ _12 = const ZeroSized: {closure@$DIR/gvn.rs:612:19: 612:21} as fn() (PointerCoercion(ClosureFnPointer(Safe))); ++ _13 = const ZeroSized: {closure@$DIR/gvn.rs:614:19: 614:21}; ++ _12 = const ZeroSized: {closure@$DIR/gvn.rs:614:19: 614:21} as fn() (PointerCoercion(ClosureFnPointer(Safe))); StorageDead(_13); StorageLive(_14); StorageLive(_15); diff --git a/tests/mir-opt/gvn.fn_pointers.GVN.panic-unwind.diff b/tests/mir-opt/gvn.fn_pointers.GVN.panic-unwind.diff index 3c5fd944d6b..e5f865b74b9 100644 --- a/tests/mir-opt/gvn.fn_pointers.GVN.panic-unwind.diff +++ b/tests/mir-opt/gvn.fn_pointers.GVN.panic-unwind.diff @@ -8,10 +8,10 @@ let mut _3: fn(u8) -> u8; let _5: (); let mut _6: fn(u8) -> u8; - let mut _9: {closure@$DIR/gvn.rs:612:19: 612:21}; + let mut _9: {closure@$DIR/gvn.rs:614:19: 614:21}; let _10: (); let mut _11: fn(); - let mut _13: {closure@$DIR/gvn.rs:612:19: 612:21}; + let mut _13: {closure@$DIR/gvn.rs:614:19: 614:21}; let _14: (); let mut _15: fn(); scope 1 { @@ -19,7 +19,7 @@ let _4: fn(u8) -> u8; scope 2 { debug g => _4; - let _7: {closure@$DIR/gvn.rs:612:19: 612:21}; + let _7: {closure@$DIR/gvn.rs:614:19: 614:21}; scope 3 { debug closure => _7; let _8: fn(); @@ -62,16 +62,16 @@ StorageDead(_6); StorageDead(_5); - StorageLive(_7); -- _7 = {closure@$DIR/gvn.rs:612:19: 612:21}; +- _7 = {closure@$DIR/gvn.rs:614:19: 614:21}; - StorageLive(_8); + nop; -+ _7 = const ZeroSized: {closure@$DIR/gvn.rs:612:19: 612:21}; ++ _7 = const ZeroSized: {closure@$DIR/gvn.rs:614:19: 614:21}; + nop; StorageLive(_9); - _9 = _7; - _8 = move _9 as fn() (PointerCoercion(ClosureFnPointer(Safe))); -+ _9 = const ZeroSized: {closure@$DIR/gvn.rs:612:19: 612:21}; -+ _8 = const ZeroSized: {closure@$DIR/gvn.rs:612:19: 612:21} as fn() (PointerCoercion(ClosureFnPointer(Safe))); ++ _9 = const ZeroSized: {closure@$DIR/gvn.rs:614:19: 614:21}; ++ _8 = const ZeroSized: {closure@$DIR/gvn.rs:614:19: 614:21} as fn() (PointerCoercion(ClosureFnPointer(Safe))); StorageDead(_9); StorageLive(_10); StorageLive(_11); @@ -88,8 +88,8 @@ StorageLive(_13); - _13 = _7; - _12 = move _13 as fn() (PointerCoercion(ClosureFnPointer(Safe))); -+ _13 = const ZeroSized: {closure@$DIR/gvn.rs:612:19: 612:21}; -+ _12 = const ZeroSized: {closure@$DIR/gvn.rs:612:19: 612:21} as fn() (PointerCoercion(ClosureFnPointer(Safe))); ++ _13 = const ZeroSized: {closure@$DIR/gvn.rs:614:19: 614:21}; ++ _12 = const ZeroSized: {closure@$DIR/gvn.rs:614:19: 614:21} as fn() (PointerCoercion(ClosureFnPointer(Safe))); StorageDead(_13); StorageLive(_14); StorageLive(_15); diff --git a/tests/mir-opt/gvn.generic_cast_metadata.GVN.panic-abort.diff b/tests/mir-opt/gvn.generic_cast_metadata.GVN.panic-abort.diff new file mode 100644 index 00000000000..1d462a8a23c --- /dev/null +++ b/tests/mir-opt/gvn.generic_cast_metadata.GVN.panic-abort.diff @@ -0,0 +1,38 @@ +- // MIR for `generic_cast_metadata` before GVN ++ // MIR for `generic_cast_metadata` after GVN + + fn generic_cast_metadata(_1: *const [T], _2: *const A, _3: *const B) -> () { + let mut _0: (); + let mut _4: *const T; + let mut _5: (); + let mut _6: *const (&A, [T]); + let mut _7: usize; + let mut _8: *const (T, B); + let mut _9: <B as std::ptr::Pointee>::Metadata; + let mut _10: *const (T, A); + let mut _11: <A as std::ptr::Pointee>::Metadata; + let mut _12: *mut A; + let mut _13: <A as std::ptr::Pointee>::Metadata; + let mut _14: *mut B; + let mut _15: <B as std::ptr::Pointee>::Metadata; + + bb0: { + _4 = _1 as *const T (PtrToPtr); + _5 = PtrMetadata(_4); + _6 = _1 as *const (&A, [T]) (PtrToPtr); +- _7 = PtrMetadata(_6); ++ _7 = PtrMetadata(_1); + _8 = _2 as *const (T, B) (PtrToPtr); + _9 = PtrMetadata(_8); + _10 = _2 as *const (T, A) (PtrToPtr); +- _11 = PtrMetadata(_10); ++ _11 = PtrMetadata(_2); + _12 = _3 as *mut A (PtrToPtr); + _13 = PtrMetadata(_12); + _14 = _3 as *mut B (PtrToPtr); +- _15 = PtrMetadata(_14); ++ _15 = PtrMetadata(_3); + return; + } + } + diff --git a/tests/mir-opt/gvn.generic_cast_metadata.GVN.panic-unwind.diff b/tests/mir-opt/gvn.generic_cast_metadata.GVN.panic-unwind.diff new file mode 100644 index 00000000000..1d462a8a23c --- /dev/null +++ b/tests/mir-opt/gvn.generic_cast_metadata.GVN.panic-unwind.diff @@ -0,0 +1,38 @@ +- // MIR for `generic_cast_metadata` before GVN ++ // MIR for `generic_cast_metadata` after GVN + + fn generic_cast_metadata(_1: *const [T], _2: *const A, _3: *const B) -> () { + let mut _0: (); + let mut _4: *const T; + let mut _5: (); + let mut _6: *const (&A, [T]); + let mut _7: usize; + let mut _8: *const (T, B); + let mut _9: <B as std::ptr::Pointee>::Metadata; + let mut _10: *const (T, A); + let mut _11: <A as std::ptr::Pointee>::Metadata; + let mut _12: *mut A; + let mut _13: <A as std::ptr::Pointee>::Metadata; + let mut _14: *mut B; + let mut _15: <B as std::ptr::Pointee>::Metadata; + + bb0: { + _4 = _1 as *const T (PtrToPtr); + _5 = PtrMetadata(_4); + _6 = _1 as *const (&A, [T]) (PtrToPtr); +- _7 = PtrMetadata(_6); ++ _7 = PtrMetadata(_1); + _8 = _2 as *const (T, B) (PtrToPtr); + _9 = PtrMetadata(_8); + _10 = _2 as *const (T, A) (PtrToPtr); +- _11 = PtrMetadata(_10); ++ _11 = PtrMetadata(_2); + _12 = _3 as *mut A (PtrToPtr); + _13 = PtrMetadata(_12); + _14 = _3 as *mut B (PtrToPtr); +- _15 = PtrMetadata(_14); ++ _15 = PtrMetadata(_3); + return; + } + } + diff --git a/tests/mir-opt/gvn.manual_slice_mut_len.GVN.panic-abort.diff b/tests/mir-opt/gvn.manual_slice_mut_len.GVN.panic-abort.diff new file mode 100644 index 00000000000..c877d8a3c0e --- /dev/null +++ b/tests/mir-opt/gvn.manual_slice_mut_len.GVN.panic-abort.diff @@ -0,0 +1,41 @@ +- // MIR for `manual_slice_mut_len` before GVN ++ // MIR for `manual_slice_mut_len` after GVN + + fn manual_slice_mut_len(_1: &mut [i32]) -> usize { + debug x => _1; + let mut _0: usize; + let _2: *mut [i32]; + let mut _4: *mut [i32]; + let mut _5: *const [i32]; + scope 1 { + debug x => _2; + let _3: *const [i32]; + scope 2 { + debug x => _3; + } + } + + bb0: { +- StorageLive(_2); ++ nop; + _2 = &raw mut (*_1); +- StorageLive(_3); ++ nop; + StorageLive(_4); + _4 = _2; +- _3 = move _4 as *const [i32] (PtrToPtr); ++ _3 = _2 as *const [i32] (PtrToPtr); + StorageDead(_4); + StorageLive(_5); + _5 = _3; +- _0 = PtrMetadata(move _5); ++ _0 = PtrMetadata(_1); + StorageDead(_5); +- StorageDead(_3); +- StorageDead(_2); ++ nop; ++ nop; + return; + } + } + diff --git a/tests/mir-opt/gvn.manual_slice_mut_len.GVN.panic-unwind.diff b/tests/mir-opt/gvn.manual_slice_mut_len.GVN.panic-unwind.diff new file mode 100644 index 00000000000..c877d8a3c0e --- /dev/null +++ b/tests/mir-opt/gvn.manual_slice_mut_len.GVN.panic-unwind.diff @@ -0,0 +1,41 @@ +- // MIR for `manual_slice_mut_len` before GVN ++ // MIR for `manual_slice_mut_len` after GVN + + fn manual_slice_mut_len(_1: &mut [i32]) -> usize { + debug x => _1; + let mut _0: usize; + let _2: *mut [i32]; + let mut _4: *mut [i32]; + let mut _5: *const [i32]; + scope 1 { + debug x => _2; + let _3: *const [i32]; + scope 2 { + debug x => _3; + } + } + + bb0: { +- StorageLive(_2); ++ nop; + _2 = &raw mut (*_1); +- StorageLive(_3); ++ nop; + StorageLive(_4); + _4 = _2; +- _3 = move _4 as *const [i32] (PtrToPtr); ++ _3 = _2 as *const [i32] (PtrToPtr); + StorageDead(_4); + StorageLive(_5); + _5 = _3; +- _0 = PtrMetadata(move _5); ++ _0 = PtrMetadata(_1); + StorageDead(_5); +- StorageDead(_3); +- StorageDead(_2); ++ nop; ++ nop; + return; + } + } + diff --git a/tests/mir-opt/gvn.rs b/tests/mir-opt/gvn.rs index 720018f112e..8bc2550b8f5 100644 --- a/tests/mir-opt/gvn.rs +++ b/tests/mir-opt/gvn.rs @@ -7,7 +7,9 @@ #![feature(custom_mir)] #![feature(core_intrinsics)] #![feature(freeze)] +#![allow(ambiguous_wide_pointer_comparisons)] #![allow(unconditional_panic)] +#![allow(unused)] use std::intrinsics::mir::*; use std::marker::Freeze; @@ -816,6 +818,71 @@ fn casts_before_aggregate_raw_ptr(x: *const u32) -> *const [u8] { std::intrinsics::aggregate_raw_ptr(x, 4) } +fn manual_slice_mut_len(x: &mut [i32]) -> usize { + // CHECK-LABEL: fn manual_slice_mut_len + // CHECK: _0 = PtrMetadata(_1); + let x: *mut [i32] = x; + let x: *const [i32] = x; + std::intrinsics::ptr_metadata(x) +} + +// `.len()` on arrays ends up being something like this +fn array_len(x: &mut [i32; 42]) -> usize { + // CHECK-LABEL: fn array_len + // CHECK: _0 = const 42_usize; + let x: &[i32] = x; + std::intrinsics::ptr_metadata(x) +} + +#[custom_mir(dialect = "runtime")] +fn generic_cast_metadata<T, A: ?Sized, B: ?Sized>(ps: *const [T], pa: *const A, pb: *const B) { + // CHECK-LABEL: fn generic_cast_metadata + mir! { + { + // These tests check that we correctly do or don't elide casts + // when the pointee metadata do or don't match, respectively. + + // Metadata usize -> (), do not optimize. + // CHECK: [[T:_.+]] = _1 as + // CHECK-NEXT: PtrMetadata([[T]]) + let t1 = CastPtrToPtr::<_, *const T>(ps); + let m1 = PtrMetadata(t1); + + // `(&A, [T])` has `usize` metadata, same as `[T]`, yes optimize. + // CHECK: [[T:_.+]] = _1 as + // CHECK-NEXT: PtrMetadata(_1) + let t2 = CastPtrToPtr::<_, *const (&A, [T])>(ps); + let m2 = PtrMetadata(t2); + + // Tail `A` and tail `B`, do not optimize. + // CHECK: [[T:_.+]] = _2 as + // CHECK-NEXT: PtrMetadata([[T]]) + let t3 = CastPtrToPtr::<_, *const (T, B)>(pa); + let m3 = PtrMetadata(t3); + + // Both have tail `A`, yes optimize. + // CHECK: [[T:_.+]] = _2 as + // CHECK-NEXT: PtrMetadata(_2) + let t4 = CastPtrToPtr::<_, *const (T, A)>(pa); + let m4 = PtrMetadata(t4); + + // Tail `B` and tail `A`, do not optimize. + // CHECK: [[T:_.+]] = _3 as + // CHECK-NEXT: PtrMetadata([[T]]) + let t5 = CastPtrToPtr::<_, *mut A>(pb); + let m5 = PtrMetadata(t5); + + // Both have tail `B`, yes optimize. + // CHECK: [[T:_.+]] = _3 as + // CHECK-NEXT: PtrMetadata(_3) + let t6 = CastPtrToPtr::<_, *mut B>(pb); + let m6 = PtrMetadata(t6); + + Return() + } + } +} + fn main() { subexpression_elimination(2, 4, 5); wrap_unwrap(5); @@ -880,3 +947,6 @@ fn identity<T>(x: T) -> T { // EMIT_MIR gvn.meta_of_ref_to_slice.GVN.diff // EMIT_MIR gvn.slice_from_raw_parts_as_ptr.GVN.diff // EMIT_MIR gvn.casts_before_aggregate_raw_ptr.GVN.diff +// EMIT_MIR gvn.manual_slice_mut_len.GVN.diff +// EMIT_MIR gvn.array_len.GVN.diff +// EMIT_MIR gvn.generic_cast_metadata.GVN.diff diff --git a/tests/mir-opt/instsimplify/casts.roundtrip.InstSimplify.diff b/tests/mir-opt/instsimplify/casts.roundtrip.InstSimplify.diff index a6d68cd4e4b..e87ac762dfe 100644 --- a/tests/mir-opt/instsimplify/casts.roundtrip.InstSimplify.diff +++ b/tests/mir-opt/instsimplify/casts.roundtrip.InstSimplify.diff @@ -14,7 +14,7 @@ StorageLive(_4); _4 = _1; _3 = move _4 as *mut u8 (PtrToPtr); - _2 = move _3 as *const u8 (PointerCoercion(MutToConstPointer)); + _2 = move _3 as *const u8 (PtrToPtr); StorageDead(_4); StorageDead(_3); - _0 = move _2 as *const u8 (PtrToPtr); diff --git a/tests/mir-opt/instsimplify/casts.rs b/tests/mir-opt/instsimplify/casts.rs index a7786fa570f..15ceea76713 100644 --- a/tests/mir-opt/instsimplify/casts.rs +++ b/tests/mir-opt/instsimplify/casts.rs @@ -21,7 +21,7 @@ pub fn roundtrip(x: *const u8) -> *const u8 { // CHECK-LABEL: fn roundtrip( // CHECK: _4 = _1; // CHECK: _3 = move _4 as *mut u8 (PtrToPtr); - // CHECK: _2 = move _3 as *const u8 (PointerCoercion(MutToConstPointer)); + // CHECK: _2 = move _3 as *const u8 (PtrToPtr); x as *mut u8 as *const u8 } diff --git a/tests/mir-opt/issue_76432.rs b/tests/mir-opt/issue_76432.rs index be5ccbd49e2..6d884063caa 100644 --- a/tests/mir-opt/issue_76432.rs +++ b/tests/mir-opt/issue_76432.rs @@ -1,11 +1,10 @@ // skip-filecheck // EMIT_MIR_FOR_EACH_PANIC_STRATEGY -//@ compile-flags: -Zmir-enable-passes=-NormalizeArrayLen // Check that we do not insert StorageDead at each target if StorageDead was never seen -// EMIT_MIR issue_76432.test.SimplifyComparisonIntegral.diff use std::fmt::Debug; +// EMIT_MIR issue_76432.test.SimplifyComparisonIntegral.diff fn test<T: Copy + Debug + PartialEq>(x: T) { let v: &[T] = &[x, x, x]; match v { diff --git a/tests/mir-opt/lower_array_len.array_bound.NormalizeArrayLen.panic-abort.diff b/tests/mir-opt/lower_array_len.array_bound.GVN.panic-abort.diff index 5242c5f6afd..6c0c7a1d438 100644 --- a/tests/mir-opt/lower_array_len.array_bound.NormalizeArrayLen.panic-abort.diff +++ b/tests/mir-opt/lower_array_len.array_bound.GVN.panic-abort.diff @@ -1,5 +1,5 @@ -- // MIR for `array_bound` before NormalizeArrayLen -+ // MIR for `array_bound` after NormalizeArrayLen +- // MIR for `array_bound` before GVN ++ // MIR for `array_bound` after GVN fn array_bound(_1: usize, _2: &[u8; N]) -> u8 { debug index => _1; @@ -24,14 +24,15 @@ _7 = &(*_2); _6 = move _7 as &[u8] (PointerCoercion(Unsize)); StorageDead(_7); -- _5 = Len((*_6)); +- _5 = PtrMetadata(move _6); + _5 = const N; goto -> bb1; } bb1: { StorageDead(_6); - _3 = Lt(move _4, move _5); +- _3 = Lt(move _4, move _5); ++ _3 = Lt(_1, move _5); switchInt(move _3) -> [0: bb4, otherwise: bb2]; } @@ -40,13 +41,17 @@ StorageDead(_4); StorageLive(_8); _8 = _1; - _9 = Len((*_2)); - _10 = Lt(_8, _9); - assert(move _10, "index out of bounds: the length is {} but the index is {}", move _9, _8) -> [success: bb3, unwind unreachable]; +- _9 = Len((*_2)); +- _10 = Lt(_8, _9); +- assert(move _10, "index out of bounds: the length is {} but the index is {}", move _9, _8) -> [success: bb3, unwind unreachable]; ++ _9 = const N; ++ _10 = Lt(_1, const N); ++ assert(move _10, "index out of bounds: the length is {} but the index is {}", const N, _1) -> [success: bb3, unwind unreachable]; } bb3: { - _0 = (*_2)[_8]; +- _0 = (*_2)[_8]; ++ _0 = (*_2)[_1]; StorageDead(_8); goto -> bb5; } diff --git a/tests/mir-opt/lower_array_len.array_bound.NormalizeArrayLen.panic-unwind.diff b/tests/mir-opt/lower_array_len.array_bound.GVN.panic-unwind.diff index a9e99933b12..ed41703c873 100644 --- a/tests/mir-opt/lower_array_len.array_bound.NormalizeArrayLen.panic-unwind.diff +++ b/tests/mir-opt/lower_array_len.array_bound.GVN.panic-unwind.diff @@ -1,5 +1,5 @@ -- // MIR for `array_bound` before NormalizeArrayLen -+ // MIR for `array_bound` after NormalizeArrayLen +- // MIR for `array_bound` before GVN ++ // MIR for `array_bound` after GVN fn array_bound(_1: usize, _2: &[u8; N]) -> u8 { debug index => _1; @@ -24,14 +24,15 @@ _7 = &(*_2); _6 = move _7 as &[u8] (PointerCoercion(Unsize)); StorageDead(_7); -- _5 = Len((*_6)); +- _5 = PtrMetadata(move _6); + _5 = const N; goto -> bb1; } bb1: { StorageDead(_6); - _3 = Lt(move _4, move _5); +- _3 = Lt(move _4, move _5); ++ _3 = Lt(_1, move _5); switchInt(move _3) -> [0: bb4, otherwise: bb2]; } @@ -40,13 +41,17 @@ StorageDead(_4); StorageLive(_8); _8 = _1; - _9 = Len((*_2)); - _10 = Lt(_8, _9); - assert(move _10, "index out of bounds: the length is {} but the index is {}", move _9, _8) -> [success: bb3, unwind continue]; +- _9 = Len((*_2)); +- _10 = Lt(_8, _9); +- assert(move _10, "index out of bounds: the length is {} but the index is {}", move _9, _8) -> [success: bb3, unwind continue]; ++ _9 = const N; ++ _10 = Lt(_1, const N); ++ assert(move _10, "index out of bounds: the length is {} but the index is {}", const N, _1) -> [success: bb3, unwind continue]; } bb3: { - _0 = (*_2)[_8]; +- _0 = (*_2)[_8]; ++ _0 = (*_2)[_1]; StorageDead(_8); goto -> bb5; } diff --git a/tests/mir-opt/lower_array_len.array_bound_mut.NormalizeArrayLen.panic-abort.diff b/tests/mir-opt/lower_array_len.array_bound_mut.GVN.panic-abort.diff index 7749ba6beca..80e8ea37f41 100644 --- a/tests/mir-opt/lower_array_len.array_bound_mut.NormalizeArrayLen.panic-abort.diff +++ b/tests/mir-opt/lower_array_len.array_bound_mut.GVN.panic-abort.diff @@ -1,5 +1,5 @@ -- // MIR for `array_bound_mut` before NormalizeArrayLen -+ // MIR for `array_bound_mut` after NormalizeArrayLen +- // MIR for `array_bound_mut` before GVN ++ // MIR for `array_bound_mut` after GVN fn array_bound_mut(_1: usize, _2: &mut [u8; N]) -> u8 { debug index => _1; @@ -27,14 +27,15 @@ _7 = &(*_2); _6 = move _7 as &[u8] (PointerCoercion(Unsize)); StorageDead(_7); -- _5 = Len((*_6)); +- _5 = PtrMetadata(move _6); + _5 = const N; goto -> bb1; } bb1: { StorageDead(_6); - _3 = Lt(move _4, move _5); +- _3 = Lt(move _4, move _5); ++ _3 = Lt(_1, move _5); switchInt(move _3) -> [0: bb4, otherwise: bb2]; } @@ -43,13 +44,17 @@ StorageDead(_4); StorageLive(_8); _8 = _1; - _9 = Len((*_2)); - _10 = Lt(_8, _9); - assert(move _10, "index out of bounds: the length is {} but the index is {}", move _9, _8) -> [success: bb3, unwind unreachable]; +- _9 = Len((*_2)); +- _10 = Lt(_8, _9); +- assert(move _10, "index out of bounds: the length is {} but the index is {}", move _9, _8) -> [success: bb3, unwind unreachable]; ++ _9 = const N; ++ _10 = Lt(_1, const N); ++ assert(move _10, "index out of bounds: the length is {} but the index is {}", const N, _1) -> [success: bb3, unwind unreachable]; } bb3: { - _0 = (*_2)[_8]; +- _0 = (*_2)[_8]; ++ _0 = (*_2)[_1]; StorageDead(_8); goto -> bb6; } @@ -59,13 +64,17 @@ StorageDead(_4); StorageLive(_11); _11 = const 0_usize; - _12 = Len((*_2)); - _13 = Lt(_11, _12); - assert(move _13, "index out of bounds: the length is {} but the index is {}", move _12, _11) -> [success: bb5, unwind unreachable]; +- _12 = Len((*_2)); +- _13 = Lt(_11, _12); +- assert(move _13, "index out of bounds: the length is {} but the index is {}", move _12, _11) -> [success: bb5, unwind unreachable]; ++ _12 = const N; ++ _13 = Lt(const 0_usize, const N); ++ assert(move _13, "index out of bounds: the length is {} but the index is {}", const N, const 0_usize) -> [success: bb5, unwind unreachable]; } bb5: { - (*_2)[_11] = const 42_u8; +- (*_2)[_11] = const 42_u8; ++ (*_2)[0 of 1] = const 42_u8; StorageDead(_11); _0 = const 42_u8; goto -> bb6; diff --git a/tests/mir-opt/lower_array_len.array_bound_mut.NormalizeArrayLen.panic-unwind.diff b/tests/mir-opt/lower_array_len.array_bound_mut.GVN.panic-unwind.diff index fcc2c1653dc..6e67a6c17ef 100644 --- a/tests/mir-opt/lower_array_len.array_bound_mut.NormalizeArrayLen.panic-unwind.diff +++ b/tests/mir-opt/lower_array_len.array_bound_mut.GVN.panic-unwind.diff @@ -1,5 +1,5 @@ -- // MIR for `array_bound_mut` before NormalizeArrayLen -+ // MIR for `array_bound_mut` after NormalizeArrayLen +- // MIR for `array_bound_mut` before GVN ++ // MIR for `array_bound_mut` after GVN fn array_bound_mut(_1: usize, _2: &mut [u8; N]) -> u8 { debug index => _1; @@ -27,14 +27,15 @@ _7 = &(*_2); _6 = move _7 as &[u8] (PointerCoercion(Unsize)); StorageDead(_7); -- _5 = Len((*_6)); +- _5 = PtrMetadata(move _6); + _5 = const N; goto -> bb1; } bb1: { StorageDead(_6); - _3 = Lt(move _4, move _5); +- _3 = Lt(move _4, move _5); ++ _3 = Lt(_1, move _5); switchInt(move _3) -> [0: bb4, otherwise: bb2]; } @@ -43,13 +44,17 @@ StorageDead(_4); StorageLive(_8); _8 = _1; - _9 = Len((*_2)); - _10 = Lt(_8, _9); - assert(move _10, "index out of bounds: the length is {} but the index is {}", move _9, _8) -> [success: bb3, unwind continue]; +- _9 = Len((*_2)); +- _10 = Lt(_8, _9); +- assert(move _10, "index out of bounds: the length is {} but the index is {}", move _9, _8) -> [success: bb3, unwind continue]; ++ _9 = const N; ++ _10 = Lt(_1, const N); ++ assert(move _10, "index out of bounds: the length is {} but the index is {}", const N, _1) -> [success: bb3, unwind continue]; } bb3: { - _0 = (*_2)[_8]; +- _0 = (*_2)[_8]; ++ _0 = (*_2)[_1]; StorageDead(_8); goto -> bb6; } @@ -59,13 +64,17 @@ StorageDead(_4); StorageLive(_11); _11 = const 0_usize; - _12 = Len((*_2)); - _13 = Lt(_11, _12); - assert(move _13, "index out of bounds: the length is {} but the index is {}", move _12, _11) -> [success: bb5, unwind continue]; +- _12 = Len((*_2)); +- _13 = Lt(_11, _12); +- assert(move _13, "index out of bounds: the length is {} but the index is {}", move _12, _11) -> [success: bb5, unwind continue]; ++ _12 = const N; ++ _13 = Lt(const 0_usize, const N); ++ assert(move _13, "index out of bounds: the length is {} but the index is {}", const N, const 0_usize) -> [success: bb5, unwind continue]; } bb5: { - (*_2)[_11] = const 42_u8; +- (*_2)[_11] = const 42_u8; ++ (*_2)[0 of 1] = const 42_u8; StorageDead(_11); _0 = const 42_u8; goto -> bb6; diff --git a/tests/mir-opt/lower_array_len.array_len.NormalizeArrayLen.panic-abort.diff b/tests/mir-opt/lower_array_len.array_len.GVN.panic-abort.diff index 1bdc62183c3..9c1b9a708c5 100644 --- a/tests/mir-opt/lower_array_len.array_len.NormalizeArrayLen.panic-abort.diff +++ b/tests/mir-opt/lower_array_len.array_len.GVN.panic-abort.diff @@ -1,5 +1,5 @@ -- // MIR for `array_len` before NormalizeArrayLen -+ // MIR for `array_len` after NormalizeArrayLen +- // MIR for `array_len` before GVN ++ // MIR for `array_len` after GVN fn array_len(_1: &[u8; N]) -> usize { debug arr => _1; @@ -13,7 +13,7 @@ _3 = &(*_1); _2 = move _3 as &[u8] (PointerCoercion(Unsize)); StorageDead(_3); -- _0 = Len((*_2)); +- _0 = PtrMetadata(move _2); + _0 = const N; goto -> bb1; } diff --git a/tests/mir-opt/lower_array_len.array_len.NormalizeArrayLen.panic-unwind.diff b/tests/mir-opt/lower_array_len.array_len.GVN.panic-unwind.diff index 1bdc62183c3..9c1b9a708c5 100644 --- a/tests/mir-opt/lower_array_len.array_len.NormalizeArrayLen.panic-unwind.diff +++ b/tests/mir-opt/lower_array_len.array_len.GVN.panic-unwind.diff @@ -1,5 +1,5 @@ -- // MIR for `array_len` before NormalizeArrayLen -+ // MIR for `array_len` after NormalizeArrayLen +- // MIR for `array_len` before GVN ++ // MIR for `array_len` after GVN fn array_len(_1: &[u8; N]) -> usize { debug arr => _1; @@ -13,7 +13,7 @@ _3 = &(*_1); _2 = move _3 as &[u8] (PointerCoercion(Unsize)); StorageDead(_3); -- _0 = Len((*_2)); +- _0 = PtrMetadata(move _2); + _0 = const N; goto -> bb1; } diff --git a/tests/mir-opt/lower_array_len.array_len_by_value.NormalizeArrayLen.panic-abort.diff b/tests/mir-opt/lower_array_len.array_len_by_value.GVN.panic-abort.diff index 9862b2fad8e..97fa503ac2e 100644 --- a/tests/mir-opt/lower_array_len.array_len_by_value.NormalizeArrayLen.panic-abort.diff +++ b/tests/mir-opt/lower_array_len.array_len_by_value.GVN.panic-abort.diff @@ -1,5 +1,5 @@ -- // MIR for `array_len_by_value` before NormalizeArrayLen -+ // MIR for `array_len_by_value` after NormalizeArrayLen +- // MIR for `array_len_by_value` before GVN ++ // MIR for `array_len_by_value` after GVN fn array_len_by_value(_1: [u8; N]) -> usize { debug arr => _1; @@ -13,7 +13,7 @@ _3 = &_1; _2 = move _3 as &[u8] (PointerCoercion(Unsize)); StorageDead(_3); -- _0 = Len((*_2)); +- _0 = PtrMetadata(move _2); + _0 = const N; goto -> bb1; } diff --git a/tests/mir-opt/lower_array_len.array_len_by_value.NormalizeArrayLen.panic-unwind.diff b/tests/mir-opt/lower_array_len.array_len_by_value.GVN.panic-unwind.diff index 9862b2fad8e..97fa503ac2e 100644 --- a/tests/mir-opt/lower_array_len.array_len_by_value.NormalizeArrayLen.panic-unwind.diff +++ b/tests/mir-opt/lower_array_len.array_len_by_value.GVN.panic-unwind.diff @@ -1,5 +1,5 @@ -- // MIR for `array_len_by_value` before NormalizeArrayLen -+ // MIR for `array_len_by_value` after NormalizeArrayLen +- // MIR for `array_len_by_value` before GVN ++ // MIR for `array_len_by_value` after GVN fn array_len_by_value(_1: [u8; N]) -> usize { debug arr => _1; @@ -13,7 +13,7 @@ _3 = &_1; _2 = move _3 as &[u8] (PointerCoercion(Unsize)); StorageDead(_3); -- _0 = Len((*_2)); +- _0 = PtrMetadata(move _2); + _0 = const N; goto -> bb1; } diff --git a/tests/mir-opt/lower_array_len.array_len_raw.NormalizeArrayLen.panic-abort.diff b/tests/mir-opt/lower_array_len.array_len_raw.GVN.panic-abort.diff index 633a344a2ed..b5e8b66813a 100644 --- a/tests/mir-opt/lower_array_len.array_len_raw.NormalizeArrayLen.panic-abort.diff +++ b/tests/mir-opt/lower_array_len.array_len_raw.GVN.panic-abort.diff @@ -1,5 +1,5 @@ -- // MIR for `array_len_raw` before NormalizeArrayLen -+ // MIR for `array_len_raw` after NormalizeArrayLen +- // MIR for `array_len_raw` before GVN ++ // MIR for `array_len_raw` after GVN fn array_len_raw(_1: [u8; N]) -> usize { debug arr => _1; @@ -18,7 +18,8 @@ } bb0: { - StorageLive(_2); +- StorageLive(_2); ++ nop; StorageLive(_3); StorageLive(_4); _4 = &_1; @@ -32,7 +33,7 @@ StorageLive(_7); _7 = &(*_5); _6 = &(*_7); -- _0 = Len((*_6)); +- _0 = PtrMetadata(move _6); + _0 = const N; goto -> bb1; } @@ -40,7 +41,8 @@ bb1: { StorageDead(_6); StorageDead(_5); - StorageDead(_2); +- StorageDead(_2); ++ nop; StorageDead(_7); return; } diff --git a/tests/mir-opt/lower_array_len.array_len_raw.NormalizeArrayLen.panic-unwind.diff b/tests/mir-opt/lower_array_len.array_len_raw.GVN.panic-unwind.diff index 633a344a2ed..b5e8b66813a 100644 --- a/tests/mir-opt/lower_array_len.array_len_raw.NormalizeArrayLen.panic-unwind.diff +++ b/tests/mir-opt/lower_array_len.array_len_raw.GVN.panic-unwind.diff @@ -1,5 +1,5 @@ -- // MIR for `array_len_raw` before NormalizeArrayLen -+ // MIR for `array_len_raw` after NormalizeArrayLen +- // MIR for `array_len_raw` before GVN ++ // MIR for `array_len_raw` after GVN fn array_len_raw(_1: [u8; N]) -> usize { debug arr => _1; @@ -18,7 +18,8 @@ } bb0: { - StorageLive(_2); +- StorageLive(_2); ++ nop; StorageLive(_3); StorageLive(_4); _4 = &_1; @@ -32,7 +33,7 @@ StorageLive(_7); _7 = &(*_5); _6 = &(*_7); -- _0 = Len((*_6)); +- _0 = PtrMetadata(move _6); + _0 = const N; goto -> bb1; } @@ -40,7 +41,8 @@ bb1: { StorageDead(_6); StorageDead(_5); - StorageDead(_2); +- StorageDead(_2); ++ nop; StorageDead(_7); return; } diff --git a/tests/mir-opt/lower_array_len.array_len_reborrow.NormalizeArrayLen.panic-abort.diff b/tests/mir-opt/lower_array_len.array_len_reborrow.GVN.panic-abort.diff index ecba06a2e4d..0299c6acd80 100644 --- a/tests/mir-opt/lower_array_len.array_len_reborrow.NormalizeArrayLen.panic-abort.diff +++ b/tests/mir-opt/lower_array_len.array_len_reborrow.GVN.panic-abort.diff @@ -1,5 +1,5 @@ -- // MIR for `array_len_reborrow` before NormalizeArrayLen -+ // MIR for `array_len_reborrow` after NormalizeArrayLen +- // MIR for `array_len_reborrow` before GVN ++ // MIR for `array_len_reborrow` after GVN fn array_len_reborrow(_1: [u8; N]) -> usize { debug arr => _1; @@ -17,7 +17,8 @@ } bb0: { - StorageLive(_2); +- StorageLive(_2); ++ nop; StorageLive(_3); StorageLive(_4); _4 = &mut _1; @@ -29,7 +30,7 @@ _5 = &(*_2); StorageLive(_6); _6 = &(*_5); -- _0 = Len((*_6)); +- _0 = PtrMetadata(move _6); + _0 = const N; goto -> bb1; } @@ -37,7 +38,8 @@ bb1: { StorageDead(_6); StorageDead(_5); - StorageDead(_2); +- StorageDead(_2); ++ nop; return; } } diff --git a/tests/mir-opt/lower_array_len.array_len_reborrow.NormalizeArrayLen.panic-unwind.diff b/tests/mir-opt/lower_array_len.array_len_reborrow.GVN.panic-unwind.diff index ecba06a2e4d..0299c6acd80 100644 --- a/tests/mir-opt/lower_array_len.array_len_reborrow.NormalizeArrayLen.panic-unwind.diff +++ b/tests/mir-opt/lower_array_len.array_len_reborrow.GVN.panic-unwind.diff @@ -1,5 +1,5 @@ -- // MIR for `array_len_reborrow` before NormalizeArrayLen -+ // MIR for `array_len_reborrow` after NormalizeArrayLen +- // MIR for `array_len_reborrow` before GVN ++ // MIR for `array_len_reborrow` after GVN fn array_len_reborrow(_1: [u8; N]) -> usize { debug arr => _1; @@ -17,7 +17,8 @@ } bb0: { - StorageLive(_2); +- StorageLive(_2); ++ nop; StorageLive(_3); StorageLive(_4); _4 = &mut _1; @@ -29,7 +30,7 @@ _5 = &(*_2); StorageLive(_6); _6 = &(*_5); -- _0 = Len((*_6)); +- _0 = PtrMetadata(move _6); + _0 = const N; goto -> bb1; } @@ -37,7 +38,8 @@ bb1: { StorageDead(_6); StorageDead(_5); - StorageDead(_2); +- StorageDead(_2); ++ nop; return; } } diff --git a/tests/mir-opt/lower_array_len.rs b/tests/mir-opt/lower_array_len.rs index 62fc9ef67d6..caa598d067a 100644 --- a/tests/mir-opt/lower_array_len.rs +++ b/tests/mir-opt/lower_array_len.rs @@ -1,20 +1,20 @@ // EMIT_MIR_FOR_EACH_PANIC_STRATEGY -//@ test-mir-pass: NormalizeArrayLen +//@ test-mir-pass: GVN //@ compile-flags: -Zmir-enable-passes=+LowerSliceLenCalls -// EMIT_MIR lower_array_len.array_bound.NormalizeArrayLen.diff +// EMIT_MIR lower_array_len.array_bound.GVN.diff pub fn array_bound<const N: usize>(index: usize, slice: &[u8; N]) -> u8 { // CHECK-LABEL: fn array_bound( // CHECK: [[len:_.*]] = const N; - // CHECK: Lt(move {{_.*}}, move [[len]]); + // CHECK: Lt(_1, move [[len]]); if index < slice.len() { slice[index] } else { 42 } } -// EMIT_MIR lower_array_len.array_bound_mut.NormalizeArrayLen.diff +// EMIT_MIR lower_array_len.array_bound_mut.GVN.diff pub fn array_bound_mut<const N: usize>(index: usize, slice: &mut [u8; N]) -> u8 { // CHECK-LABEL: fn array_bound_mut( // CHECK: [[len:_.*]] = const N; - // CHECK: Lt(move {{_.*}}, move [[len]]); + // CHECK: Lt(_1, move [[len]]); if index < slice.len() { slice[index] } else { @@ -24,21 +24,21 @@ pub fn array_bound_mut<const N: usize>(index: usize, slice: &mut [u8; N]) -> u8 } } -// EMIT_MIR lower_array_len.array_len.NormalizeArrayLen.diff +// EMIT_MIR lower_array_len.array_len.GVN.diff pub fn array_len<const N: usize>(arr: &[u8; N]) -> usize { // CHECK-LABEL: fn array_len( // CHECK: _0 = const N; arr.len() } -// EMIT_MIR lower_array_len.array_len_by_value.NormalizeArrayLen.diff +// EMIT_MIR lower_array_len.array_len_by_value.GVN.diff pub fn array_len_by_value<const N: usize>(arr: [u8; N]) -> usize { // CHECK-LABEL: fn array_len_by_value( // CHECK: _0 = const N; arr.len() } -// EMIT_MIR lower_array_len.array_len_reborrow.NormalizeArrayLen.diff +// EMIT_MIR lower_array_len.array_len_reborrow.GVN.diff pub fn array_len_reborrow<const N: usize>(mut arr: [u8; N]) -> usize { // CHECK-LABEL: fn array_len_reborrow( // CHECK: _0 = const N; @@ -47,7 +47,7 @@ pub fn array_len_reborrow<const N: usize>(mut arr: [u8; N]) -> usize { arr.len() } -// EMIT_MIR lower_array_len.array_len_raw.NormalizeArrayLen.diff +// EMIT_MIR lower_array_len.array_len_raw.GVN.diff pub fn array_len_raw<const N: usize>(arr: [u8; N]) -> usize { // CHECK-LABEL: fn array_len_raw( // CHECK: _0 = const N; diff --git a/tests/mir-opt/lower_slice_len.bound.LowerSliceLenCalls.panic-abort.diff b/tests/mir-opt/lower_slice_len.bound.LowerSliceLenCalls.panic-abort.diff index 7f752ca0f5a..a212ee67881 100644 --- a/tests/mir-opt/lower_slice_len.bound.LowerSliceLenCalls.panic-abort.diff +++ b/tests/mir-opt/lower_slice_len.bound.LowerSliceLenCalls.panic-abort.diff @@ -21,7 +21,7 @@ StorageLive(_6); _6 = &(*_2); - _5 = core::slice::<impl [u8]>::len(move _6) -> [return: bb1, unwind unreachable]; -+ _5 = Len((*_6)); ++ _5 = PtrMetadata(move _6); + goto -> bb1; } diff --git a/tests/mir-opt/lower_slice_len.bound.LowerSliceLenCalls.panic-unwind.diff b/tests/mir-opt/lower_slice_len.bound.LowerSliceLenCalls.panic-unwind.diff index d73b563a0e5..38ec8a5b0c7 100644 --- a/tests/mir-opt/lower_slice_len.bound.LowerSliceLenCalls.panic-unwind.diff +++ b/tests/mir-opt/lower_slice_len.bound.LowerSliceLenCalls.panic-unwind.diff @@ -21,7 +21,7 @@ StorageLive(_6); _6 = &(*_2); - _5 = core::slice::<impl [u8]>::len(move _6) -> [return: bb1, unwind continue]; -+ _5 = Len((*_6)); ++ _5 = PtrMetadata(move _6); + goto -> bb1; } diff --git a/tests/mir-opt/or_pattern.rs b/tests/mir-opt/or_pattern.rs new file mode 100644 index 00000000000..0ad0ce8ead1 --- /dev/null +++ b/tests/mir-opt/or_pattern.rs @@ -0,0 +1,24 @@ +// skip-filecheck + +// EMIT_MIR or_pattern.shortcut_second_or.SimplifyCfg-initial.after.mir +fn shortcut_second_or() { + // Check that after matching `0`, failing to match `2 | 3` skips trying to match `(1, 2 | 3)`. + match ((0, 0), 0) { + (x @ (0, _) | x @ (_, 1), y @ 2 | y @ 3) => {} + _ => {} + } +} + +// EMIT_MIR or_pattern.single_switchint.SimplifyCfg-initial.after.mir +fn single_switchint() { + // Check how many `SwitchInt`s we do. In theory a single one is necessary. + match (1, true) { + (1, true) => 1, + (2, false) => 2, + (1 | 2, true | false) => 3, + (3 | 4, true | false) => 4, + _ => 5, + }; +} + +fn main() {} diff --git a/tests/mir-opt/or_pattern.shortcut_second_or.SimplifyCfg-initial.after.mir b/tests/mir-opt/or_pattern.shortcut_second_or.SimplifyCfg-initial.after.mir new file mode 100644 index 00000000000..56edd38a6da --- /dev/null +++ b/tests/mir-opt/or_pattern.shortcut_second_or.SimplifyCfg-initial.after.mir @@ -0,0 +1,100 @@ +// MIR for `shortcut_second_or` after SimplifyCfg-initial + +fn shortcut_second_or() -> () { + let mut _0: (); + let mut _1: ((i32, i32), i32); + let mut _2: (i32, i32); + let _3: (i32, i32); + let _4: i32; + scope 1 { + debug x => _3; + debug y => _4; + } + + bb0: { + StorageLive(_1); + StorageLive(_2); + _2 = (const 0_i32, const 0_i32); + _1 = (move _2, const 0_i32); + StorageDead(_2); + PlaceMention(_1); + switchInt(((_1.0: (i32, i32)).0: i32)) -> [0: bb4, otherwise: bb2]; + } + + bb1: { + _0 = const (); + goto -> bb14; + } + + bb2: { + switchInt(((_1.0: (i32, i32)).1: i32)) -> [1: bb3, otherwise: bb1]; + } + + bb3: { + switchInt((_1.1: i32)) -> [2: bb7, 3: bb8, otherwise: bb1]; + } + + bb4: { + switchInt((_1.1: i32)) -> [2: bb5, 3: bb6, otherwise: bb1]; + } + + bb5: { + falseEdge -> [real: bb10, imaginary: bb6]; + } + + bb6: { + falseEdge -> [real: bb11, imaginary: bb2]; + } + + bb7: { + falseEdge -> [real: bb12, imaginary: bb8]; + } + + bb8: { + falseEdge -> [real: bb13, imaginary: bb1]; + } + + bb9: { + _0 = const (); + StorageDead(_4); + StorageDead(_3); + goto -> bb14; + } + + bb10: { + StorageLive(_3); + _3 = (_1.0: (i32, i32)); + StorageLive(_4); + _4 = (_1.1: i32); + goto -> bb9; + } + + bb11: { + StorageLive(_3); + _3 = (_1.0: (i32, i32)); + StorageLive(_4); + _4 = (_1.1: i32); + goto -> bb9; + } + + bb12: { + StorageLive(_3); + _3 = (_1.0: (i32, i32)); + StorageLive(_4); + _4 = (_1.1: i32); + goto -> bb9; + } + + bb13: { + StorageLive(_3); + _3 = (_1.0: (i32, i32)); + StorageLive(_4); + _4 = (_1.1: i32); + goto -> bb9; + } + + bb14: { + StorageDead(_1); + return; + } +} diff --git a/tests/mir-opt/or_pattern.single_switchint.SimplifyCfg-initial.after.mir b/tests/mir-opt/or_pattern.single_switchint.SimplifyCfg-initial.after.mir new file mode 100644 index 00000000000..eafe95b4a11 --- /dev/null +++ b/tests/mir-opt/or_pattern.single_switchint.SimplifyCfg-initial.after.mir @@ -0,0 +1,75 @@ +// MIR for `single_switchint` after SimplifyCfg-initial + +fn single_switchint() -> () { + let mut _0: (); + let _1: i32; + let mut _2: (i32, bool); + + bb0: { + StorageLive(_1); + StorageLive(_2); + _2 = (const 1_i32, const true); + PlaceMention(_2); + switchInt((_2.0: i32)) -> [1: bb2, 2: bb4, otherwise: bb1]; + } + + bb1: { + switchInt((_2.0: i32)) -> [3: bb8, 4: bb8, otherwise: bb7]; + } + + bb2: { + switchInt((_2.1: bool)) -> [0: bb6, otherwise: bb3]; + } + + bb3: { + falseEdge -> [real: bb9, imaginary: bb4]; + } + + bb4: { + switchInt((_2.1: bool)) -> [0: bb5, otherwise: bb6]; + } + + bb5: { + falseEdge -> [real: bb10, imaginary: bb6]; + } + + bb6: { + falseEdge -> [real: bb11, imaginary: bb1]; + } + + bb7: { + _1 = const 5_i32; + goto -> bb13; + } + + bb8: { + falseEdge -> [real: bb12, imaginary: bb7]; + } + + bb9: { + _1 = const 1_i32; + goto -> bb13; + } + + bb10: { + _1 = const 2_i32; + goto -> bb13; + } + + bb11: { + _1 = const 3_i32; + goto -> bb13; + } + + bb12: { + _1 = const 4_i32; + goto -> bb13; + } + + bb13: { + StorageDead(_2); + StorageDead(_1); + _0 = const (); + return; + } +} diff --git a/tests/mir-opt/pre-codegen/checked_ops.step_forward.PreCodegen.after.panic-abort.mir b/tests/mir-opt/pre-codegen/checked_ops.step_forward.PreCodegen.after.panic-abort.mir index cfb9134a1f1..e31a8cb6937 100644 --- a/tests/mir-opt/pre-codegen/checked_ops.step_forward.PreCodegen.after.panic-abort.mir +++ b/tests/mir-opt/pre-codegen/checked_ops.step_forward.PreCodegen.after.panic-abort.mir @@ -4,12 +4,87 @@ fn step_forward(_1: u16, _2: usize) -> u16 { debug x => _1; debug n => _2; let mut _0: u16; + scope 1 (inlined <u16 as Step>::forward) { + let mut _8: u16; + scope 2 { + } + scope 3 (inlined <u16 as Step>::forward_checked) { + scope 4 { + scope 6 (inlined core::num::<impl u16>::checked_add) { + let mut _7: bool; + scope 7 { + } + scope 8 (inlined core::num::<impl u16>::overflowing_add) { + let mut _5: (u16, bool); + let _6: bool; + scope 9 { + } + } + } + } + scope 5 (inlined convert::num::ptr_try_from_impls::<impl TryFrom<usize> for u16>::try_from) { + let mut _3: bool; + let mut _4: u16; + } + } + scope 10 (inlined Option::<u16>::is_none) { + scope 11 (inlined Option::<u16>::is_some) { + } + } + scope 12 (inlined core::num::<impl u16>::wrapping_add) { + } + } bb0: { - _0 = <u16 as Step>::forward(move _1, move _2) -> [return: bb1, unwind unreachable]; + StorageLive(_4); + StorageLive(_3); + _3 = Gt(_2, const 65535_usize); + switchInt(move _3) -> [0: bb1, otherwise: bb5]; } bb1: { + _4 = _2 as u16 (IntToInt); + StorageDead(_3); + StorageLive(_6); + StorageLive(_5); + _5 = AddWithOverflow(_1, _4); + _6 = (_5.1: bool); + StorageDead(_5); + StorageLive(_7); + _7 = unlikely(move _6) -> [return: bb2, unwind unreachable]; + } + + bb2: { + switchInt(move _7) -> [0: bb3, otherwise: bb4]; + } + + bb3: { + StorageDead(_7); + StorageDead(_6); + goto -> bb7; + } + + bb4: { + StorageDead(_7); + StorageDead(_6); + goto -> bb6; + } + + bb5: { + StorageDead(_3); + goto -> bb6; + } + + bb6: { + assert(!const true, "attempt to compute `{} + {}`, which would overflow", const core::num::<impl u16>::MAX, const 1_u16) -> [success: bb7, unwind unreachable]; + } + + bb7: { + StorageLive(_8); + _8 = _2 as u16 (IntToInt); + _0 = Add(_1, _8); + StorageDead(_8); + StorageDead(_4); return; } } diff --git a/tests/mir-opt/pre-codegen/checked_ops.step_forward.PreCodegen.after.panic-unwind.mir b/tests/mir-opt/pre-codegen/checked_ops.step_forward.PreCodegen.after.panic-unwind.mir index cacc1224aba..8cc9be27e21 100644 --- a/tests/mir-opt/pre-codegen/checked_ops.step_forward.PreCodegen.after.panic-unwind.mir +++ b/tests/mir-opt/pre-codegen/checked_ops.step_forward.PreCodegen.after.panic-unwind.mir @@ -4,12 +4,87 @@ fn step_forward(_1: u16, _2: usize) -> u16 { debug x => _1; debug n => _2; let mut _0: u16; + scope 1 (inlined <u16 as Step>::forward) { + let mut _8: u16; + scope 2 { + } + scope 3 (inlined <u16 as Step>::forward_checked) { + scope 4 { + scope 6 (inlined core::num::<impl u16>::checked_add) { + let mut _7: bool; + scope 7 { + } + scope 8 (inlined core::num::<impl u16>::overflowing_add) { + let mut _5: (u16, bool); + let _6: bool; + scope 9 { + } + } + } + } + scope 5 (inlined convert::num::ptr_try_from_impls::<impl TryFrom<usize> for u16>::try_from) { + let mut _3: bool; + let mut _4: u16; + } + } + scope 10 (inlined Option::<u16>::is_none) { + scope 11 (inlined Option::<u16>::is_some) { + } + } + scope 12 (inlined core::num::<impl u16>::wrapping_add) { + } + } bb0: { - _0 = <u16 as Step>::forward(move _1, move _2) -> [return: bb1, unwind continue]; + StorageLive(_4); + StorageLive(_3); + _3 = Gt(_2, const 65535_usize); + switchInt(move _3) -> [0: bb1, otherwise: bb5]; } bb1: { + _4 = _2 as u16 (IntToInt); + StorageDead(_3); + StorageLive(_6); + StorageLive(_5); + _5 = AddWithOverflow(_1, _4); + _6 = (_5.1: bool); + StorageDead(_5); + StorageLive(_7); + _7 = unlikely(move _6) -> [return: bb2, unwind unreachable]; + } + + bb2: { + switchInt(move _7) -> [0: bb3, otherwise: bb4]; + } + + bb3: { + StorageDead(_7); + StorageDead(_6); + goto -> bb7; + } + + bb4: { + StorageDead(_7); + StorageDead(_6); + goto -> bb6; + } + + bb5: { + StorageDead(_3); + goto -> bb6; + } + + bb6: { + assert(!const true, "attempt to compute `{} + {}`, which would overflow", const core::num::<impl u16>::MAX, const 1_u16) -> [success: bb7, unwind continue]; + } + + bb7: { + StorageLive(_8); + _8 = _2 as u16 (IntToInt); + _0 = Add(_1, _8); + StorageDead(_8); + StorageDead(_4); return; } } diff --git a/tests/mir-opt/pre-codegen/loops.mapped.PreCodegen.after.mir b/tests/mir-opt/pre-codegen/loops.mapped.PreCodegen.after.mir index b800a1be22b..51d41e9ff05 100644 --- a/tests/mir-opt/pre-codegen/loops.mapped.PreCodegen.after.mir +++ b/tests/mir-opt/pre-codegen/loops.mapped.PreCodegen.after.mir @@ -7,14 +7,30 @@ fn mapped(_1: impl Iterator<Item = T>, _2: impl Fn(T) -> U) -> () { let mut _3: std::iter::Map<impl Iterator<Item = T>, impl Fn(T) -> U>; let mut _4: std::iter::Map<impl Iterator<Item = T>, impl Fn(T) -> U>; let mut _5: &mut std::iter::Map<impl Iterator<Item = T>, impl Fn(T) -> U>; - let mut _6: std::option::Option<U>; - let mut _7: isize; - let _9: (); + let mut _13: std::option::Option<U>; + let _15: (); scope 1 { debug iter => _4; - let _8: U; + let _14: U; scope 2 { - debug x => _8; + debug x => _14; + } + scope 4 (inlined <Map<impl Iterator<Item = T>, impl Fn(T) -> U> as Iterator>::next) { + debug self => _5; + let mut _6: &mut impl Iterator<Item = T>; + let mut _7: std::option::Option<T>; + let mut _8: &mut impl Fn(T) -> U; + scope 5 (inlined Option::<T>::map::<U, &mut impl Fn(T) -> U>) { + debug self => _7; + debug f => _8; + let mut _9: isize; + let _10: T; + let mut _11: (T,); + let mut _12: U; + scope 6 { + debug x => _10; + } + } } } scope 3 (inlined <Map<impl Iterator<Item = T>, impl Fn(T) -> U> as IntoIterator>::into_iter) { @@ -32,20 +48,30 @@ fn mapped(_1: impl Iterator<Item = T>, _2: impl Fn(T) -> U) -> () { } bb2: { - StorageLive(_6); - StorageLive(_5); + StorageLive(_13); _5 = &mut _4; - _6 = <Map<impl Iterator<Item = T>, impl Fn(T) -> U> as Iterator>::next(move _5) -> [return: bb3, unwind: bb9]; + StorageLive(_8); + StorageLive(_7); + StorageLive(_6); + _6 = &mut (_4.0: impl Iterator<Item = T>); + _7 = <impl Iterator<Item = T> as Iterator>::next(move _6) -> [return: bb3, unwind: bb10]; } bb3: { - StorageDead(_5); - _7 = discriminant(_6); - switchInt(move _7) -> [0: bb4, 1: bb6, otherwise: bb8]; + StorageDead(_6); + _8 = &mut (_4.1: impl Fn(T) -> U); + StorageLive(_9); + StorageLive(_10); + _9 = discriminant(_7); + switchInt(move _9) -> [0: bb4, 1: bb6, otherwise: bb9]; } bb4: { - StorageDead(_6); + StorageDead(_10); + StorageDead(_9); + StorageDead(_7); + StorageDead(_8); + StorageDead(_13); drop(_4) -> [return: bb5, unwind continue]; } @@ -55,24 +81,39 @@ fn mapped(_1: impl Iterator<Item = T>, _2: impl Fn(T) -> U) -> () { } bb6: { - _8 = move ((_6 as Some).0: U); - _9 = opaque::<U>(move _8) -> [return: bb7, unwind: bb9]; + _10 = move ((_7 as Some).0: T); + StorageLive(_12); + StorageLive(_11); + _11 = (_10,); + _12 = <&mut impl Fn(T) -> U as FnOnce<(T,)>>::call_once(move _8, move _11) -> [return: bb7, unwind: bb10]; } bb7: { - StorageDead(_6); - goto -> bb2; + StorageDead(_11); + _13 = Option::<U>::Some(move _12); + StorageDead(_12); + StorageDead(_10); + StorageDead(_9); + StorageDead(_7); + StorageDead(_8); + _14 = move ((_13 as Some).0: U); + _15 = opaque::<U>(move _14) -> [return: bb8, unwind: bb10]; } bb8: { - unreachable; + StorageDead(_13); + goto -> bb2; } - bb9 (cleanup): { - drop(_4) -> [return: bb10, unwind terminate(cleanup)]; + bb9: { + unreachable; } bb10 (cleanup): { + drop(_4) -> [return: bb11, unwind terminate(cleanup)]; + } + + bb11 (cleanup): { resume; } } diff --git a/tests/mir-opt/pre-codegen/slice_index.rs b/tests/mir-opt/pre-codegen/slice_index.rs index 886e57a3380..6ddc4ad0220 100644 --- a/tests/mir-opt/pre-codegen/slice_index.rs +++ b/tests/mir-opt/pre-codegen/slice_index.rs @@ -19,7 +19,7 @@ pub fn slice_index_usize(slice: &[u32], index: usize) -> u32 { // EMIT_MIR slice_index.slice_get_mut_usize.PreCodegen.after.mir pub fn slice_get_mut_usize(slice: &mut [u32], index: usize) -> Option<&mut u32> { // CHECK-LABEL: slice_get_mut_usize - // CHECK: [[LEN:_[0-9]+]] = Len((*_1)) + // CHECK: [[LEN:_[0-9]+]] = PtrMetadata(_1) // CHECK: Lt(_2, move [[LEN]]) // CHECK-NOT: precondition_check slice.get_mut(index) diff --git a/tests/mir-opt/pre-codegen/slice_index.slice_get_mut_usize.PreCodegen.after.panic-abort.mir b/tests/mir-opt/pre-codegen/slice_index.slice_get_mut_usize.PreCodegen.after.panic-abort.mir index f2ef2b0cc3c..d7f09fafeeb 100644 --- a/tests/mir-opt/pre-codegen/slice_index.slice_get_mut_usize.PreCodegen.after.panic-abort.mir +++ b/tests/mir-opt/pre-codegen/slice_index.slice_get_mut_usize.PreCodegen.after.panic-abort.mir @@ -23,7 +23,7 @@ fn slice_get_mut_usize(_1: &mut [u32], _2: usize) -> Option<&mut u32> { StorageLive(_7); StorageLive(_4); StorageLive(_3); - _3 = Len((*_1)); + _3 = PtrMetadata(_1); _4 = Lt(_2, move _3); switchInt(move _4) -> [0: bb1, otherwise: bb2]; } diff --git a/tests/mir-opt/pre-codegen/slice_index.slice_get_mut_usize.PreCodegen.after.panic-unwind.mir b/tests/mir-opt/pre-codegen/slice_index.slice_get_mut_usize.PreCodegen.after.panic-unwind.mir index f2ef2b0cc3c..d7f09fafeeb 100644 --- a/tests/mir-opt/pre-codegen/slice_index.slice_get_mut_usize.PreCodegen.after.panic-unwind.mir +++ b/tests/mir-opt/pre-codegen/slice_index.slice_get_mut_usize.PreCodegen.after.panic-unwind.mir @@ -23,7 +23,7 @@ fn slice_get_mut_usize(_1: &mut [u32], _2: usize) -> Option<&mut u32> { StorageLive(_7); StorageLive(_4); StorageLive(_3); - _3 = Len((*_1)); + _3 = PtrMetadata(_1); _4 = Lt(_2, move _3); switchInt(move _4) -> [0: bb1, otherwise: bb2]; } diff --git a/tests/mir-opt/pre-codegen/slice_index.slice_get_unchecked_mut_range.PreCodegen.after.panic-abort.mir b/tests/mir-opt/pre-codegen/slice_index.slice_get_unchecked_mut_range.PreCodegen.after.panic-abort.mir index 5e0398d1114..2f13cfa4dab 100644 --- a/tests/mir-opt/pre-codegen/slice_index.slice_get_unchecked_mut_range.PreCodegen.after.panic-abort.mir +++ b/tests/mir-opt/pre-codegen/slice_index.slice_get_unchecked_mut_range.PreCodegen.after.panic-abort.mir @@ -8,25 +8,24 @@ fn slice_get_unchecked_mut_range(_1: &mut [u32], _2: std::ops::Range<usize>) -> let mut _4: usize; scope 1 (inlined core::slice::<impl [u32]>::get_unchecked_mut::<std::ops::Range<usize>>) { let mut _5: *mut [u32]; - let mut _12: *mut [u32]; + let mut _11: *mut [u32]; scope 2 (inlined <std::ops::Range<usize> as SliceIndex<[u32]>>::get_unchecked_mut) { - let mut _7: usize; - let _8: (); - let _9: usize; + let mut _6: usize; + let _7: (); + let _8: usize; scope 3 { scope 6 (inlined core::slice::index::get_offset_len_mut_noubcheck::<u32>) { - let _11: *mut u32; + let _10: *mut u32; scope 7 { } scope 8 (inlined core::slice::index::get_mut_noubcheck::<u32>) { - let _10: *mut u32; + let _9: *mut u32; scope 9 { } } } } scope 4 (inlined std::ptr::mut_ptr::<impl *mut [u32]>::len) { - let mut _6: *const [u32]; scope 5 (inlined std::ptr::metadata::<[u32]>) { } } @@ -38,28 +37,25 @@ fn slice_get_unchecked_mut_range(_1: &mut [u32], _2: std::ops::Range<usize>) -> _4 = move (_2.1: usize); StorageLive(_5); _5 = &raw mut (*_1); - StorageLive(_9); - StorageLive(_7); + StorageLive(_8); StorageLive(_6); - _6 = _5 as *const [u32] (PointerCoercion(MutToConstPointer)); - _7 = PtrMetadata(_6); - StorageDead(_6); - _8 = <std::ops::Range<usize> as SliceIndex<[T]>>::get_unchecked_mut::precondition_check(_3, _4, move _7) -> [return: bb1, unwind unreachable]; + _6 = PtrMetadata(_1); + _7 = <std::ops::Range<usize> as SliceIndex<[T]>>::get_unchecked_mut::precondition_check(_3, _4, move _6) -> [return: bb1, unwind unreachable]; } bb1: { - StorageDead(_7); - _9 = SubUnchecked(_4, _3); - StorageLive(_11); + StorageDead(_6); + _8 = SubUnchecked(_4, _3); StorageLive(_10); - _10 = _5 as *mut u32 (PtrToPtr); - _11 = Offset(_10, _3); - StorageDead(_10); - _12 = *mut [u32] from (_11, _9); - StorageDead(_11); + StorageLive(_9); + _9 = _5 as *mut u32 (PtrToPtr); + _10 = Offset(_9, _3); StorageDead(_9); + _11 = *mut [u32] from (_10, _8); + StorageDead(_10); + StorageDead(_8); StorageDead(_5); - _0 = &mut (*_12); + _0 = &mut (*_11); return; } } diff --git a/tests/mir-opt/pre-codegen/slice_index.slice_get_unchecked_mut_range.PreCodegen.after.panic-unwind.mir b/tests/mir-opt/pre-codegen/slice_index.slice_get_unchecked_mut_range.PreCodegen.after.panic-unwind.mir index 5e0398d1114..2f13cfa4dab 100644 --- a/tests/mir-opt/pre-codegen/slice_index.slice_get_unchecked_mut_range.PreCodegen.after.panic-unwind.mir +++ b/tests/mir-opt/pre-codegen/slice_index.slice_get_unchecked_mut_range.PreCodegen.after.panic-unwind.mir @@ -8,25 +8,24 @@ fn slice_get_unchecked_mut_range(_1: &mut [u32], _2: std::ops::Range<usize>) -> let mut _4: usize; scope 1 (inlined core::slice::<impl [u32]>::get_unchecked_mut::<std::ops::Range<usize>>) { let mut _5: *mut [u32]; - let mut _12: *mut [u32]; + let mut _11: *mut [u32]; scope 2 (inlined <std::ops::Range<usize> as SliceIndex<[u32]>>::get_unchecked_mut) { - let mut _7: usize; - let _8: (); - let _9: usize; + let mut _6: usize; + let _7: (); + let _8: usize; scope 3 { scope 6 (inlined core::slice::index::get_offset_len_mut_noubcheck::<u32>) { - let _11: *mut u32; + let _10: *mut u32; scope 7 { } scope 8 (inlined core::slice::index::get_mut_noubcheck::<u32>) { - let _10: *mut u32; + let _9: *mut u32; scope 9 { } } } } scope 4 (inlined std::ptr::mut_ptr::<impl *mut [u32]>::len) { - let mut _6: *const [u32]; scope 5 (inlined std::ptr::metadata::<[u32]>) { } } @@ -38,28 +37,25 @@ fn slice_get_unchecked_mut_range(_1: &mut [u32], _2: std::ops::Range<usize>) -> _4 = move (_2.1: usize); StorageLive(_5); _5 = &raw mut (*_1); - StorageLive(_9); - StorageLive(_7); + StorageLive(_8); StorageLive(_6); - _6 = _5 as *const [u32] (PointerCoercion(MutToConstPointer)); - _7 = PtrMetadata(_6); - StorageDead(_6); - _8 = <std::ops::Range<usize> as SliceIndex<[T]>>::get_unchecked_mut::precondition_check(_3, _4, move _7) -> [return: bb1, unwind unreachable]; + _6 = PtrMetadata(_1); + _7 = <std::ops::Range<usize> as SliceIndex<[T]>>::get_unchecked_mut::precondition_check(_3, _4, move _6) -> [return: bb1, unwind unreachable]; } bb1: { - StorageDead(_7); - _9 = SubUnchecked(_4, _3); - StorageLive(_11); + StorageDead(_6); + _8 = SubUnchecked(_4, _3); StorageLive(_10); - _10 = _5 as *mut u32 (PtrToPtr); - _11 = Offset(_10, _3); - StorageDead(_10); - _12 = *mut [u32] from (_11, _9); - StorageDead(_11); + StorageLive(_9); + _9 = _5 as *mut u32 (PtrToPtr); + _10 = Offset(_9, _3); StorageDead(_9); + _11 = *mut [u32] from (_10, _8); + StorageDead(_10); + StorageDead(_8); StorageDead(_5); - _0 = &mut (*_12); + _0 = &mut (*_11); return; } } diff --git a/tests/mir-opt/pre-codegen/slice_iter.enumerated_loop.PreCodegen.after.panic-abort.mir b/tests/mir-opt/pre-codegen/slice_iter.enumerated_loop.PreCodegen.after.panic-abort.mir index 8f41fb70925..953e7550479 100644 --- a/tests/mir-opt/pre-codegen/slice_iter.enumerated_loop.PreCodegen.after.panic-abort.mir +++ b/tests/mir-opt/pre-codegen/slice_iter.enumerated_loop.PreCodegen.after.panic-abort.mir @@ -7,19 +7,44 @@ fn enumerated_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () { let mut _11: std::slice::Iter<'_, T>; let mut _12: std::iter::Enumerate<std::slice::Iter<'_, T>>; let mut _13: std::iter::Enumerate<std::slice::Iter<'_, T>>; - let mut _14: &mut std::iter::Enumerate<std::slice::Iter<'_, T>>; - let mut _15: std::option::Option<(usize, &T)>; - let mut _16: isize; - let mut _19: &impl Fn(usize, &T); - let mut _20: (usize, &T); - let _21: (); + let mut _21: std::option::Option<(usize, &T)>; + let mut _24: &impl Fn(usize, &T); + let mut _25: (usize, &T); + let _26: (); scope 1 { debug iter => _13; - let _17: usize; - let _18: &T; + let _22: usize; + let _23: &T; scope 2 { - debug i => _17; - debug x => _18; + debug i => _22; + debug x => _23; + } + scope 17 (inlined <Enumerate<std::slice::Iter<'_, T>> as Iterator>::next) { + let mut _14: &mut std::slice::Iter<'_, T>; + let mut _15: std::option::Option<&T>; + let mut _19: (usize, bool); + let mut _20: (usize, &T); + scope 18 { + let _18: usize; + scope 23 { + } + } + scope 19 { + scope 20 { + scope 26 (inlined <Option<(usize, &T)> as FromResidual>::from_residual) { + } + } + } + scope 21 { + scope 22 { + } + } + scope 24 (inlined <Option<&T> as Try>::branch) { + let mut _16: isize; + let _17: &T; + scope 25 { + } + } } } scope 3 (inlined core::slice::<impl [T]>::iter) { @@ -65,7 +90,7 @@ fn enumerated_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () { StorageLive(_6); StorageLive(_4); StorageLive(_5); - _3 = Len((*_1)); + _3 = PtrMetadata(_1); _4 = &raw const (*_1); _5 = _4 as *const T (PtrToPtr); _6 = NonNull::<T> { pointer: _5 }; @@ -79,7 +104,7 @@ fn enumerated_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () { _7 = _4 as *mut T (PtrToPtr); _8 = Offset(_7, _3); StorageDead(_7); - _9 = move _8 as *const T (PointerCoercion(MutToConstPointer)); + _9 = move _8 as *const T (PtrToPtr); StorageDead(_8); goto -> bb3; } @@ -107,20 +132,28 @@ fn enumerated_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () { } bb4: { + StorageLive(_21); + StorageLive(_18); + StorageLive(_19); StorageLive(_15); StorageLive(_14); - _14 = &mut _13; - _15 = <Enumerate<std::slice::Iter<'_, T>> as Iterator>::next(move _14) -> [return: bb5, unwind unreachable]; + _14 = &mut (_13.0: std::slice::Iter<'_, T>); + _15 = <std::slice::Iter<'_, T> as Iterator>::next(move _14) -> [return: bb5, unwind unreachable]; } bb5: { StorageDead(_14); + StorageLive(_16); _16 = discriminant(_15); - switchInt(move _16) -> [0: bb6, 1: bb8, otherwise: bb10]; + switchInt(move _16) -> [0: bb6, 1: bb8, otherwise: bb11]; } bb6: { + StorageDead(_16); StorageDead(_15); + StorageDead(_19); + StorageDead(_18); + StorageDead(_21); StorageDead(_13); drop(_2) -> [return: bb7, unwind unreachable]; } @@ -130,23 +163,39 @@ fn enumerated_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () { } bb8: { - _17 = (((_15 as Some).0: (usize, &T)).0: usize); - _18 = (((_15 as Some).0: (usize, &T)).1: &T); - StorageLive(_19); - _19 = &_2; - StorageLive(_20); - _20 = (_17, _18); - _21 = <impl Fn(usize, &T) as Fn<(usize, &T)>>::call(move _19, move _20) -> [return: bb9, unwind unreachable]; + _17 = move ((_15 as Some).0: &T); + StorageDead(_16); + StorageDead(_15); + _18 = (_13.1: usize); + _19 = AddWithOverflow((_13.1: usize), const 1_usize); + assert(!move (_19.1: bool), "attempt to compute `{} + {}`, which would overflow", (_13.1: usize), const 1_usize) -> [success: bb9, unwind unreachable]; } bb9: { + (_13.1: usize) = move (_19.0: usize); + StorageLive(_20); + _20 = (_18, _17); + _21 = Option::<(usize, &T)>::Some(move _20); StorageDead(_20); StorageDead(_19); - StorageDead(_15); - goto -> bb4; + StorageDead(_18); + _22 = (((_21 as Some).0: (usize, &T)).0: usize); + _23 = (((_21 as Some).0: (usize, &T)).1: &T); + StorageLive(_24); + _24 = &_2; + StorageLive(_25); + _25 = (_22, _23); + _26 = <impl Fn(usize, &T) as Fn<(usize, &T)>>::call(move _24, move _25) -> [return: bb10, unwind unreachable]; } bb10: { + StorageDead(_25); + StorageDead(_24); + StorageDead(_21); + goto -> bb4; + } + + bb11: { unreachable; } } diff --git a/tests/mir-opt/pre-codegen/slice_iter.enumerated_loop.PreCodegen.after.panic-unwind.mir b/tests/mir-opt/pre-codegen/slice_iter.enumerated_loop.PreCodegen.after.panic-unwind.mir index 17cf305468e..d5fdb2e08cc 100644 --- a/tests/mir-opt/pre-codegen/slice_iter.enumerated_loop.PreCodegen.after.panic-unwind.mir +++ b/tests/mir-opt/pre-codegen/slice_iter.enumerated_loop.PreCodegen.after.panic-unwind.mir @@ -65,7 +65,7 @@ fn enumerated_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () { StorageLive(_6); StorageLive(_4); StorageLive(_5); - _3 = Len((*_1)); + _3 = PtrMetadata(_1); _4 = &raw const (*_1); _5 = _4 as *const T (PtrToPtr); _6 = NonNull::<T> { pointer: _5 }; @@ -79,7 +79,7 @@ fn enumerated_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () { _7 = _4 as *mut T (PtrToPtr); _8 = Offset(_7, _3); StorageDead(_7); - _9 = move _8 as *const T (PointerCoercion(MutToConstPointer)); + _9 = move _8 as *const T (PtrToPtr); StorageDead(_8); goto -> bb3; } diff --git a/tests/mir-opt/pre-codegen/slice_iter.forward_loop.PreCodegen.after.panic-abort.mir b/tests/mir-opt/pre-codegen/slice_iter.forward_loop.PreCodegen.after.panic-abort.mir index 3c1bbdc8742..cc2beac06f2 100644 --- a/tests/mir-opt/pre-codegen/slice_iter.forward_loop.PreCodegen.after.panic-abort.mir +++ b/tests/mir-opt/pre-codegen/slice_iter.forward_loop.PreCodegen.after.panic-abort.mir @@ -57,7 +57,7 @@ fn forward_loop(_1: &[T], _2: impl Fn(&T)) -> () { StorageLive(_6); StorageLive(_4); StorageLive(_5); - _3 = Len((*_1)); + _3 = PtrMetadata(_1); _4 = &raw const (*_1); _5 = _4 as *const T (PtrToPtr); _6 = NonNull::<T> { pointer: _5 }; @@ -71,7 +71,7 @@ fn forward_loop(_1: &[T], _2: impl Fn(&T)) -> () { _7 = _4 as *mut T (PtrToPtr); _8 = Offset(_7, _3); StorageDead(_7); - _9 = move _8 as *const T (PointerCoercion(MutToConstPointer)); + _9 = move _8 as *const T (PtrToPtr); StorageDead(_8); goto -> bb3; } diff --git a/tests/mir-opt/pre-codegen/slice_iter.forward_loop.PreCodegen.after.panic-unwind.mir b/tests/mir-opt/pre-codegen/slice_iter.forward_loop.PreCodegen.after.panic-unwind.mir index b2ec1ea7b9f..d66edb28570 100644 --- a/tests/mir-opt/pre-codegen/slice_iter.forward_loop.PreCodegen.after.panic-unwind.mir +++ b/tests/mir-opt/pre-codegen/slice_iter.forward_loop.PreCodegen.after.panic-unwind.mir @@ -57,7 +57,7 @@ fn forward_loop(_1: &[T], _2: impl Fn(&T)) -> () { StorageLive(_6); StorageLive(_4); StorageLive(_5); - _3 = Len((*_1)); + _3 = PtrMetadata(_1); _4 = &raw const (*_1); _5 = _4 as *const T (PtrToPtr); _6 = NonNull::<T> { pointer: _5 }; @@ -71,7 +71,7 @@ fn forward_loop(_1: &[T], _2: impl Fn(&T)) -> () { _7 = _4 as *mut T (PtrToPtr); _8 = Offset(_7, _3); StorageDead(_7); - _9 = move _8 as *const T (PointerCoercion(MutToConstPointer)); + _9 = move _8 as *const T (PtrToPtr); StorageDead(_8); goto -> bb3; } diff --git a/tests/mir-opt/pre-codegen/slice_iter.range_loop.PreCodegen.after.panic-abort.mir b/tests/mir-opt/pre-codegen/slice_iter.range_loop.PreCodegen.after.panic-abort.mir index dbe6f39548c..cea2fcbcdc0 100644 --- a/tests/mir-opt/pre-codegen/slice_iter.range_loop.PreCodegen.after.panic-abort.mir +++ b/tests/mir-opt/pre-codegen/slice_iter.range_loop.PreCodegen.after.panic-abort.mir @@ -40,7 +40,7 @@ fn range_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () { } bb0: { - _3 = Len((*_1)); + _3 = PtrMetadata(_1); StorageLive(_4); _4 = const 0_usize; goto -> bb1; diff --git a/tests/mir-opt/pre-codegen/slice_iter.range_loop.PreCodegen.after.panic-unwind.mir b/tests/mir-opt/pre-codegen/slice_iter.range_loop.PreCodegen.after.panic-unwind.mir index 5b6441cfb3b..bd658a770ea 100644 --- a/tests/mir-opt/pre-codegen/slice_iter.range_loop.PreCodegen.after.panic-unwind.mir +++ b/tests/mir-opt/pre-codegen/slice_iter.range_loop.PreCodegen.after.panic-unwind.mir @@ -40,7 +40,7 @@ fn range_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () { } bb0: { - _3 = Len((*_1)); + _3 = PtrMetadata(_1); StorageLive(_4); _4 = const 0_usize; goto -> bb1; diff --git a/tests/mir-opt/pre-codegen/slice_iter.reverse_loop.PreCodegen.after.panic-abort.mir b/tests/mir-opt/pre-codegen/slice_iter.reverse_loop.PreCodegen.after.panic-abort.mir index bf982f076de..fbb887fe76a 100644 --- a/tests/mir-opt/pre-codegen/slice_iter.reverse_loop.PreCodegen.after.panic-abort.mir +++ b/tests/mir-opt/pre-codegen/slice_iter.reverse_loop.PreCodegen.after.panic-abort.mir @@ -65,7 +65,7 @@ fn reverse_loop(_1: &[T], _2: impl Fn(&T)) -> () { StorageLive(_6); StorageLive(_4); StorageLive(_5); - _3 = Len((*_1)); + _3 = PtrMetadata(_1); _4 = &raw const (*_1); _5 = _4 as *const T (PtrToPtr); _6 = NonNull::<T> { pointer: _5 }; @@ -79,7 +79,7 @@ fn reverse_loop(_1: &[T], _2: impl Fn(&T)) -> () { _7 = _4 as *mut T (PtrToPtr); _8 = Offset(_7, _3); StorageDead(_7); - _9 = move _8 as *const T (PointerCoercion(MutToConstPointer)); + _9 = move _8 as *const T (PtrToPtr); StorageDead(_8); goto -> bb3; } diff --git a/tests/mir-opt/pre-codegen/slice_iter.reverse_loop.PreCodegen.after.panic-unwind.mir b/tests/mir-opt/pre-codegen/slice_iter.reverse_loop.PreCodegen.after.panic-unwind.mir index 532b8162521..db9409f72ab 100644 --- a/tests/mir-opt/pre-codegen/slice_iter.reverse_loop.PreCodegen.after.panic-unwind.mir +++ b/tests/mir-opt/pre-codegen/slice_iter.reverse_loop.PreCodegen.after.panic-unwind.mir @@ -65,7 +65,7 @@ fn reverse_loop(_1: &[T], _2: impl Fn(&T)) -> () { StorageLive(_6); StorageLive(_4); StorageLive(_5); - _3 = Len((*_1)); + _3 = PtrMetadata(_1); _4 = &raw const (*_1); _5 = _4 as *const T (PtrToPtr); _6 = NonNull::<T> { pointer: _5 }; @@ -79,7 +79,7 @@ fn reverse_loop(_1: &[T], _2: impl Fn(&T)) -> () { _7 = _4 as *mut T (PtrToPtr); _8 = Offset(_7, _3); StorageDead(_7); - _9 = move _8 as *const T (PointerCoercion(MutToConstPointer)); + _9 = move _8 as *const T (PtrToPtr); StorageDead(_8); goto -> bb3; } diff --git a/tests/mir-opt/retag.array_casts.SimplifyCfg-pre-optimizations.after.panic-abort.mir b/tests/mir-opt/retag.array_casts.SimplifyCfg-pre-optimizations.after.panic-abort.mir index f9d58ea60a3..6dba667dd15 100644 --- a/tests/mir-opt/retag.array_casts.SimplifyCfg-pre-optimizations.after.panic-abort.mir +++ b/tests/mir-opt/retag.array_casts.SimplifyCfg-pre-optimizations.after.panic-abort.mir @@ -64,7 +64,7 @@ fn array_casts() -> () { StorageLive(_4); _4 = &mut _1; _3 = &raw mut (*_4); - _2 = move _3 as *mut usize (PointerCoercion(ArrayToPointer)); + _2 = move _3 as *mut usize (PtrToPtr); StorageDead(_3); StorageDead(_4); StorageLive(_5); @@ -87,7 +87,7 @@ fn array_casts() -> () { StorageLive(_11); _11 = &_8; _10 = &raw const (*_11); - _9 = move _10 as *const usize (PointerCoercion(ArrayToPointer)); + _9 = move _10 as *const usize (PtrToPtr); StorageDead(_10); StorageDead(_11); StorageLive(_12); diff --git a/tests/mir-opt/retag.array_casts.SimplifyCfg-pre-optimizations.after.panic-unwind.mir b/tests/mir-opt/retag.array_casts.SimplifyCfg-pre-optimizations.after.panic-unwind.mir index b0b70cd5d91..fa812002e26 100644 --- a/tests/mir-opt/retag.array_casts.SimplifyCfg-pre-optimizations.after.panic-unwind.mir +++ b/tests/mir-opt/retag.array_casts.SimplifyCfg-pre-optimizations.after.panic-unwind.mir @@ -64,7 +64,7 @@ fn array_casts() -> () { StorageLive(_4); _4 = &mut _1; _3 = &raw mut (*_4); - _2 = move _3 as *mut usize (PointerCoercion(ArrayToPointer)); + _2 = move _3 as *mut usize (PtrToPtr); StorageDead(_3); StorageDead(_4); StorageLive(_5); @@ -87,7 +87,7 @@ fn array_casts() -> () { StorageLive(_11); _11 = &_8; _10 = &raw const (*_11); - _9 = move _10 as *const usize (PointerCoercion(ArrayToPointer)); + _9 = move _10 as *const usize (PtrToPtr); StorageDead(_10); StorageDead(_11); StorageLive(_12); diff --git a/tests/run-make/issue-51671/app.rs b/tests/run-make/bin-emit-no-symbols/app.rs index e9dc1e9744f..e9dc1e9744f 100644 --- a/tests/run-make/issue-51671/app.rs +++ b/tests/run-make/bin-emit-no-symbols/app.rs diff --git a/tests/run-make/bin-emit-no-symbols/rmake.rs b/tests/run-make/bin-emit-no-symbols/rmake.rs new file mode 100644 index 00000000000..5586e53c050 --- /dev/null +++ b/tests/run-make/bin-emit-no-symbols/rmake.rs @@ -0,0 +1,16 @@ +// When setting the crate type as a "bin" (in app.rs), +// this could cause a bug where some symbols would not be +// emitted in the object files. This has been fixed, and +// this test checks that the correct symbols have been successfully +// emitted inside the object files. +// See https://github.com/rust-lang/rust/issues/51671 + +use run_make_support::{llvm_readobj, rustc}; + +fn main() { + rustc().emit("obj").input("app.rs").run(); + let out = llvm_readobj().input("app.o").arg("--symbols").run(); + out.assert_stdout_contains("rust_begin_unwind"); + out.assert_stdout_contains("rust_eh_personality"); + out.assert_stdout_contains("__rg_oom"); +} diff --git a/tests/run-make/comment-section/Makefile b/tests/run-make/comment-section/Makefile deleted file mode 100644 index d0b98176ffe..00000000000 --- a/tests/run-make/comment-section/Makefile +++ /dev/null @@ -1,18 +0,0 @@ -# Both GCC and Clang write by default a `.comment` section with compiler information. Rustc received a similar .comment section, so this tests checks that this section properly appears. -# See https://github.com/rust-lang/rust/commit/74b8d324eb77a8f337b35dc68ac91b0c2c06debc - -include ../tools.mk - -# only-linux - -all: - echo 'fn main(){}' | $(RUSTC) - --emit=link,obj -Csave-temps --target=$(TARGET) - - # Check linked output has a `.comment` section with the expected content. - readelf -p '.comment' $(TMPDIR)/rust_out | $(CGREP) -F 'rustc version 1.' - - # Check all object files (including temporary outputs) have a `.comment` - # section with the expected content. - set -e; for f in $(TMPDIR)/*.o; do \ - readelf -p '.comment' $$f | $(CGREP) -F 'rustc version 1.'; \ - done diff --git a/tests/run-make/comment-section/rmake.rs b/tests/run-make/comment-section/rmake.rs new file mode 100644 index 00000000000..41df04da7a5 --- /dev/null +++ b/tests/run-make/comment-section/rmake.rs @@ -0,0 +1,47 @@ +// Both GCC and Clang write by default a `.comment` section with compiler information. +// Rustc received a similar .comment section, so this tests checks that this section +// properly appears. +// See https://github.com/rust-lang/rust/commit/74b8d324eb77a8f337b35dc68ac91b0c2c06debc + +//@ only-linux +// FIXME(jieyouxu): check cross-compile setup +//@ ignore-cross-compile + +use std::path::PathBuf; + +use run_make_support::llvm_readobj; +use run_make_support::rustc; +use run_make_support::{cwd, env_var, read_dir, run_in_tmpdir}; + +fn main() { + let target = env_var("TARGET"); + + rustc() + .arg("-") + .stdin("fn main() {}") + .emit("link,obj") + .arg("-Csave-temps") + .target(&target) + .run(); + + // Check linked output has a `.comment` section with the expected content. + llvm_readobj() + .section(".comment") + .input("rust_out") + .run() + .assert_stdout_contains("rustc version 1."); + + // Check all object files (including temporary outputs) have a `.comment` + // section with the expected content. + read_dir(cwd(), |f| { + if !f.extension().is_some_and(|ext| ext == "o") { + return; + } + + llvm_readobj() + .section(".comment") + .input(&f) + .run() + .assert_stdout_contains("rustc version 1."); + }); +} diff --git a/tests/run-make/compressed-debuginfo/Makefile b/tests/run-make/compressed-debuginfo/Makefile deleted file mode 100644 index d2f24dde00d..00000000000 --- a/tests/run-make/compressed-debuginfo/Makefile +++ /dev/null @@ -1,14 +0,0 @@ -# ignore-cross-compile -include ../tools.mk - -# only-linux -# -# This tests debuginfo-compression. - -all: zlib zstandard - -zlib: - test "`$(RUSTC) --crate-name=foo --crate-type=lib --emit=obj -C debuginfo=full -Z debuginfo-compression=zlib foo.rs 2>&1 | sed 's/.*unknown.*zlib.*/missing/' | head -n 1`" = missing || readelf -t $(TMPDIR)/foo.o | grep -q ZLIB - -zstandard: - test "`$(RUSTC) --crate-name=foo --crate-type=lib --emit=obj -C debuginfo=full -Z debuginfo-compression=zstd foo.rs 2>&1 | sed 's/.*unknown.*zstd.*/missing/' | head -n 1`" = missing || readelf -t $(TMPDIR)/foo.o | grep -q ZST diff --git a/tests/run-make/compressed-debuginfo/rmake.rs b/tests/run-make/compressed-debuginfo/rmake.rs new file mode 100644 index 00000000000..9c6d50ab243 --- /dev/null +++ b/tests/run-make/compressed-debuginfo/rmake.rs @@ -0,0 +1,36 @@ +// Checks the `debuginfo-compression` option. + +//@ only-linux +//@ ignore-cross-compile + +// FIXME: This test isn't comprehensive and isn't covering all possible combinations. + +use run_make_support::{assert_contains, cmd, run_in_tmpdir, rustc}; + +fn check_compression(compression: &str, to_find: &str) { + run_in_tmpdir(|| { + let out = rustc() + .crate_name("foo") + .crate_type("lib") + .emit("obj") + .arg("-Cdebuginfo=full") + .arg(&format!("-Zdebuginfo-compression={compression}")) + .input("foo.rs") + .run(); + let stderr = out.stderr_utf8(); + if stderr.is_empty() { + // FIXME: `readelf` might need to be replaced with `llvm-readelf`. + cmd("readelf").arg("-t").arg("foo.o").run().assert_stdout_contains(to_find); + } else { + assert_contains( + &stderr, + &format!("unknown debuginfo compression algorithm {compression}"), + ); + } + }); +} + +fn main() { + check_compression("zlib", "ZLIB"); + check_compression("zstd", "ZSTD"); +} diff --git a/tests/run-make/debugger-visualizer-dep-info/Makefile b/tests/run-make/debugger-visualizer-dep-info/Makefile deleted file mode 100644 index 0877998a74f..00000000000 --- a/tests/run-make/debugger-visualizer-dep-info/Makefile +++ /dev/null @@ -1,9 +0,0 @@ -include ../tools.mk - -# This test makes sure that files referenced via #[debugger_visualizer] are -# included in `--emit dep-info` output. - -all: - $(RUSTC) --emit dep-info main.rs - $(CGREP) "foo.py" < $(TMPDIR)/main.d - $(CGREP) "my_visualizers/bar.natvis" < $(TMPDIR)/main.d diff --git a/tests/run-make/debugger-visualizer-dep-info/rmake.rs b/tests/run-make/debugger-visualizer-dep-info/rmake.rs new file mode 100644 index 00000000000..65ffb2373e7 --- /dev/null +++ b/tests/run-make/debugger-visualizer-dep-info/rmake.rs @@ -0,0 +1,11 @@ +// This test checks that files referenced via #[debugger_visualizer] are +// included in `--emit dep-info` output. +// See https://github.com/rust-lang/rust/pull/111641 + +use run_make_support::{invalid_utf8_contains, rustc}; + +fn main() { + rustc().emit("dep-info").input("main.rs").run(); + invalid_utf8_contains("main.d", "foo.py"); + invalid_utf8_contains("main.d", "my_visualizers/bar.natvis"); +} diff --git a/tests/run-make/extern-flag-rename-transitive/Makefile b/tests/run-make/extern-flag-rename-transitive/Makefile deleted file mode 100644 index d16a8e20868..00000000000 --- a/tests/run-make/extern-flag-rename-transitive/Makefile +++ /dev/null @@ -1,7 +0,0 @@ -include ../tools.mk - -all: - $(RUSTC) foo.rs - $(RUSTC) bar.rs - $(RUSTC) baz.rs --extern a=$(TMPDIR)/libfoo.rlib - diff --git a/tests/run-make/extern-flag-rename-transitive/rmake.rs b/tests/run-make/extern-flag-rename-transitive/rmake.rs new file mode 100644 index 00000000000..0090d487f03 --- /dev/null +++ b/tests/run-make/extern-flag-rename-transitive/rmake.rs @@ -0,0 +1,14 @@ +// In this test, baz.rs is looking for an extern crate "a" which +// does not exist, and can only run through the --extern rustc flag +// defining that the "a" crate is in fact just "foo". This test +// checks that the --extern flag takes precedence over the extern +// crate statement in the code. +// See https://github.com/rust-lang/rust/pull/52723 + +use run_make_support::{rust_lib_name, rustc}; + +fn main() { + rustc().input("foo.rs").run(); + rustc().input("bar.rs").run(); + rustc().input("baz.rs").extern_("a", rust_lib_name("foo")).run(); +} diff --git a/tests/run-make/extern-overrides-distribution/Makefile b/tests/run-make/extern-overrides-distribution/Makefile deleted file mode 100644 index bfd0dd6991b..00000000000 --- a/tests/run-make/extern-overrides-distribution/Makefile +++ /dev/null @@ -1,6 +0,0 @@ -# ignore-cross-compile -include ../tools.mk - -all: - $(RUSTC) libc.rs -Cmetadata=foo - $(RUSTC) main.rs --extern libc=$(TMPDIR)/liblibc.rlib diff --git a/tests/run-make/extern-overrides-distribution/rmake.rs b/tests/run-make/extern-overrides-distribution/rmake.rs new file mode 100644 index 00000000000..bd2553d4134 --- /dev/null +++ b/tests/run-make/extern-overrides-distribution/rmake.rs @@ -0,0 +1,14 @@ +// The --extern flag should override any "crate_type" declarations in the +// Rust files themselves. In this test, libc is compiled as "lib", but +// main.rs will only run with an rlib, which checks if the --extern flag +// is successfully overriding the default behaviour. +// See https://github.com/rust-lang/rust/pull/21782 + +//@ ignore-cross-compile + +use run_make_support::{rust_lib_name, rustc}; + +fn main() { + rustc().input("libc.rs").metadata("foo").run(); + rustc().input("main.rs").extern_("libc", rust_lib_name("libc")).run(); +} diff --git a/tests/run-make/forced-unwind-terminate-pof/Makefile b/tests/run-make/forced-unwind-terminate-pof/Makefile deleted file mode 100644 index 871621520b9..00000000000 --- a/tests/run-make/forced-unwind-terminate-pof/Makefile +++ /dev/null @@ -1,9 +0,0 @@ -# ignore-cross-compile -# only-linux -include ../tools.mk - -all: foo - $(call RUN,foo) | $(CGREP) -v "cannot unwind" - -foo: foo.rs - $(RUSTC) $< diff --git a/tests/run-make/forced-unwind-terminate-pof/foo.rs b/tests/run-make/forced-unwind-terminate-pof/foo.rs index 0a51287313f..3a847846217 100644 --- a/tests/run-make/forced-unwind-terminate-pof/foo.rs +++ b/tests/run-make/forced-unwind-terminate-pof/foo.rs @@ -1,6 +1,5 @@ // Tests that forced unwind through POF Rust frames wouldn't trigger our terminating guards. -#![feature(c_unwind)] #![no_main] extern "C-unwind" { diff --git a/tests/run-make/forced-unwind-terminate-pof/rmake.rs b/tests/run-make/forced-unwind-terminate-pof/rmake.rs new file mode 100644 index 00000000000..320ddb172b6 --- /dev/null +++ b/tests/run-make/forced-unwind-terminate-pof/rmake.rs @@ -0,0 +1,16 @@ +// During a forced unwind, crossing the non-Plain Old Frame +// would define the forced unwind as undefined behaviour, and +// immediately abort the unwinding process. This test checks +// that the forced unwinding takes precedence. +// See https://github.com/rust-lang/rust/issues/101469 + +//@ ignore-cross-compile +//@ ignore-windows +//Reason: pthread (POSIX threads) is not available on Windows + +use run_make_support::{run, rustc}; + +fn main() { + rustc().input("foo.rs").run(); + run("foo").assert_stdout_not_contains("cannot unwind"); +} diff --git a/tests/run-make/glibc-staticlib-args/Makefile b/tests/run-make/glibc-staticlib-args/Makefile deleted file mode 100644 index cad6c049e45..00000000000 --- a/tests/run-make/glibc-staticlib-args/Makefile +++ /dev/null @@ -1,13 +0,0 @@ -# ignore-cross-compile -# only-gnu -# only-linux - -include ../tools.mk - -# This ensures that std::env::args works in a library called from C on glibc Linux. - -all: - $(RUSTC) --crate-type=staticlib library.rs - $(CC) program.c $(call STATICLIB,library) $(call OUT_EXE,program) \ - $(EXTRACFLAGS) $(EXTRACXXFLAGS) - $(call RUN,program) diff --git a/tests/run-make/glibc-staticlib-args/rmake.rs b/tests/run-make/glibc-staticlib-args/rmake.rs new file mode 100644 index 00000000000..8ab10419ab9 --- /dev/null +++ b/tests/run-make/glibc-staticlib-args/rmake.rs @@ -0,0 +1,18 @@ +// This ensures that std::env::args works in a library called from C on glibc Linux. + +//@ only-gnu +//@ only-linux +//@ ignore-cross-compile + +use run_make_support::{bin_name, cc, extra_c_flags, extra_cxx_flags, run, rustc, static_lib_name}; + +fn main() { + rustc().input("library.rs").crate_type("staticlib").run(); + cc().input("program.c") + .arg(static_lib_name("library")) + .out_exe("program") + .args(&extra_c_flags()) + .args(&extra_cxx_flags()) + .run(); + run(&bin_name("program")); +} diff --git a/tests/run-make/inaccessible-temp-dir/rmake.rs b/tests/run-make/inaccessible-temp-dir/rmake.rs index be24e47b6de..c6bfae4cc01 100644 --- a/tests/run-make/inaccessible-temp-dir/rmake.rs +++ b/tests/run-make/inaccessible-temp-dir/rmake.rs @@ -19,7 +19,7 @@ // Reason: `set_readonly` has no effect on directories // and does not prevent modification. -use run_make_support::{fs_wrapper, rustc, test_while_readonly}; +use run_make_support::{fs_wrapper, rustc, target, test_while_readonly}; fn main() { // Create an inaccessible directory. @@ -28,6 +28,7 @@ fn main() { // Run rustc with `-Z temps-dir` set to a directory *inside* the inaccessible one, // so that it can't create `tmp`. rustc() + .target(&target()) .input("program.rs") .arg("-Ztemps-dir=inaccessible/tmp") .run_fail() diff --git a/tests/run-make/issue-51671/Makefile b/tests/run-make/issue-51671/Makefile deleted file mode 100644 index c9364536992..00000000000 --- a/tests/run-make/issue-51671/Makefile +++ /dev/null @@ -1,9 +0,0 @@ -include ../tools.mk - -# ignore-windows-msvc - -all: - $(RUSTC) --emit=obj app.rs - nm $(TMPDIR)/app.o | $(CGREP) rust_begin_unwind - nm $(TMPDIR)/app.o | $(CGREP) rust_eh_personality - nm $(TMPDIR)/app.o | $(CGREP) __rg_oom diff --git a/tests/run-make/link-args-order/Makefile b/tests/run-make/link-args-order/Makefile deleted file mode 100644 index c562cc1b396..00000000000 --- a/tests/run-make/link-args-order/Makefile +++ /dev/null @@ -1,10 +0,0 @@ -# ignore-msvc - -include ../tools.mk - -RUSTC_FLAGS = -C linker-flavor=ld -C link-arg=a -C link-args="b c" -C link-args="d e" -C link-arg=f -RUSTC_FLAGS_PRE = -C linker-flavor=ld -Z pre-link-arg=a -Z pre-link-args="b c" -Z pre-link-args="d e" -Z pre-link-arg=f - -all: - $(RUSTC) $(RUSTC_FLAGS) empty.rs 2>&1 | $(CGREP) '"a" "b" "c" "d" "e" "f"' - $(RUSTC) $(RUSTC_FLAGS_PRE) empty.rs 2>&1 | $(CGREP) '"a" "b" "c" "d" "e" "f"' diff --git a/tests/run-make/link-args-order/rmake.rs b/tests/run-make/link-args-order/rmake.rs new file mode 100644 index 00000000000..d238ad23f27 --- /dev/null +++ b/tests/run-make/link-args-order/rmake.rs @@ -0,0 +1,30 @@ +// Passing linker arguments to the compiler used to be lost or reordered in a messy way +// as they were passed further to the linker. This was fixed in #70665, and this test +// checks that linker arguments remain intact and in the order they were originally passed in. +// See https://github.com/rust-lang/rust/pull/70665 + +//@ ignore-msvc +// Reason: the ld linker does not exist on Windows. + +use run_make_support::rustc; + +fn main() { + rustc() + .input("empty.rs") + .linker_flavor("ld") + .link_arg("a") + .link_args("b c") + .link_args("d e") + .link_arg("f") + .run_fail() + .assert_stderr_contains(r#""a" "b" "c" "d" "e" "f""#); + rustc() + .input("empty.rs") + .linker_flavor("ld") + .arg("-Zpre-link-arg=a") + .arg("-Zpre-link-args=b c") + .arg("-Zpre-link-args=d e") + .arg("-Zpre-link-arg=f") + .run_fail() + .assert_stderr_contains(r#""a" "b" "c" "d" "e" "f""#); +} diff --git a/tests/run-make/ls-metadata/Makefile b/tests/run-make/ls-metadata/Makefile deleted file mode 100644 index f03569baef7..00000000000 --- a/tests/run-make/ls-metadata/Makefile +++ /dev/null @@ -1,8 +0,0 @@ -# ignore-cross-compile -include ../tools.mk - -all: - $(RUSTC) foo.rs - $(RUSTC) -Z ls=root $(TMPDIR)/foo - touch $(TMPDIR)/bar - $(RUSTC) -Z ls=root $(TMPDIR)/bar diff --git a/tests/run-make/ls-metadata/rmake.rs b/tests/run-make/ls-metadata/rmake.rs new file mode 100644 index 00000000000..0e60f2c4678 --- /dev/null +++ b/tests/run-make/ls-metadata/rmake.rs @@ -0,0 +1,17 @@ +// Passing invalid files to -Z ls (which lists the symbols +// defined by a library crate) used to cause a segmentation fault. +// As this was fixed in #11262, this test checks that no segfault +// occurs when passing the invalid file `bar` to -Z ls. +// See https://github.com/rust-lang/rust/issues/11259 + +//@ ignore-cross-compile + +use run_make_support::fs_wrapper; +use run_make_support::rustc; + +fn main() { + rustc().input("foo.rs").run(); + rustc().arg("-Zls=root").input("foo").run(); + fs_wrapper::create_file("bar"); + rustc().arg("-Zls=root").input("bar").run(); +} diff --git a/tests/run-make/lto-readonly-lib/Makefile b/tests/run-make/lto-readonly-lib/Makefile deleted file mode 100644 index 11d944e3e3d..00000000000 --- a/tests/run-make/lto-readonly-lib/Makefile +++ /dev/null @@ -1,13 +0,0 @@ -# ignore-cross-compile -include ../tools.mk - -all: - $(RUSTC) lib.rs - - # the compiler needs to copy and modify the rlib file when performing - # LTO, so we should ensure that it can cope with the original rlib - # being read-only. - chmod 444 $(TMPDIR)/*.rlib - - $(RUSTC) main.rs -C lto - $(call RUN,main) diff --git a/tests/run-make/lto-readonly-lib/rmake.rs b/tests/run-make/lto-readonly-lib/rmake.rs new file mode 100644 index 00000000000..9eb135addd9 --- /dev/null +++ b/tests/run-make/lto-readonly-lib/rmake.rs @@ -0,0 +1,19 @@ +// When the compiler is performing link time optimization, it will +// need to copy the original rlib file, set the copy's permissions to read/write, +// and modify that copy - even if the original +// file is read-only. This test creates a read-only rlib, and checks that +// compilation with LTO succeeds. +// See https://github.com/rust-lang/rust/pull/17619 + +//@ ignore-cross-compile + +use run_make_support::fs_wrapper; +use run_make_support::{run, rust_lib_name, rustc, test_while_readonly}; + +fn main() { + rustc().input("lib.rs").run(); + test_while_readonly(rust_lib_name("lib"), || { + rustc().input("main.rs").arg("-Clto").run(); + run("main"); + }); +} diff --git a/tests/run-make/metadata-flag-frobs-symbols/Makefile b/tests/run-make/metadata-flag-frobs-symbols/Makefile deleted file mode 100644 index 53d7d065769..00000000000 --- a/tests/run-make/metadata-flag-frobs-symbols/Makefile +++ /dev/null @@ -1,11 +0,0 @@ -# ignore-cross-compile -include ../tools.mk - -all: - $(RUSTC) foo.rs -C metadata=a -C extra-filename=-a - $(RUSTC) foo.rs -C metadata=b -C extra-filename=-b - $(RUSTC) bar.rs \ - --extern foo1=$(TMPDIR)/libfoo-a.rlib \ - --extern foo2=$(TMPDIR)/libfoo-b.rlib \ - --print link-args - $(call RUN,bar) diff --git a/tests/run-make/metadata-flag-frobs-symbols/rmake.rs b/tests/run-make/metadata-flag-frobs-symbols/rmake.rs new file mode 100644 index 00000000000..938886957fb --- /dev/null +++ b/tests/run-make/metadata-flag-frobs-symbols/rmake.rs @@ -0,0 +1,20 @@ +// In this test, foo.rs is compiled twice with different hashes tied to its +// symbols thanks to the metadata flag. bar.rs then ensures that the memory locations +// of foo's symbols are different even though they came from the same original source code. +// This checks that the metadata flag is doing its job. +// See https://github.com/rust-lang/rust/issues/14471 + +//@ ignore-cross-compile + +use run_make_support::{run, rust_lib_name, rustc}; + +fn main() { + rustc().input("foo.rs").metadata("a").extra_filename("-a").run(); + rustc().input("foo.rs").metadata("b").extra_filename("-b").run(); + rustc() + .input("bar.rs") + .extern_("foo1", rust_lib_name("foo-a")) + .extern_("foo2", rust_lib_name("foo-b")) + .run(); + run("bar"); +} diff --git a/tests/run-make/rustdoc-io-error/Makefile b/tests/run-make/rustdoc-io-error/Makefile deleted file mode 100644 index 27f5ecf94ab..00000000000 --- a/tests/run-make/rustdoc-io-error/Makefile +++ /dev/null @@ -1,20 +0,0 @@ -include ../tools.mk - -# This test verifies that rustdoc doesn't ICE when it encounters an IO error -# while generating files. Ideally this would be a rustdoc-ui test, so we could -# verify the error message as well. - -# ignore-windows -# The test uses `chmod`. - -OUTPUT_DIR := "$(TMPDIR)/rustdoc-io-error" - -# This test operates by creating a temporary directory and modifying its -# permissions so that it is not writable. We have to take special care to set -# the permissions back to normal so that it's able to be deleted later. -all: - mkdir -p $(OUTPUT_DIR) - chmod u-w $(OUTPUT_DIR) - -$(shell $(RUSTDOC) -o $(OUTPUT_DIR) foo.rs) - chmod u+w $(OUTPUT_DIR) - exit $($(.SHELLSTATUS) -eq 1) diff --git a/tests/run-make/rustdoc-io-error/rmake.rs b/tests/run-make/rustdoc-io-error/rmake.rs new file mode 100644 index 00000000000..d60e4438e6f --- /dev/null +++ b/tests/run-make/rustdoc-io-error/rmake.rs @@ -0,0 +1,31 @@ +// This test verifies that rustdoc doesn't ICE when it encounters an IO error +// while generating files. Ideally this would be a rustdoc-ui test, so we could +// verify the error message as well. +// +// It operates by creating a temporary directory and modifying its +// permissions so that it is not writable. We have to take special care to set +// the permissions back to normal so that it's able to be deleted later. + +//@ ignore-windows - the `set_readonly` functions doesn't work on folders. +//@ ignore-arm - weird file perms on armhf-gnu + +use run_make_support::{path, rustdoc}; +use std::fs; + +fn main() { + let out_dir = path("rustdoc-io-error"); + let output = fs::create_dir(&out_dir).unwrap(); + let mut permissions = fs::metadata(&out_dir).unwrap().permissions(); + let original_permissions = permissions.clone(); + + permissions.set_readonly(true); + fs::set_permissions(&out_dir, permissions).unwrap(); + + let output = rustdoc().input("foo.rs").output(&out_dir).env("RUST_BACKTRACE", "1").run_fail(); + + fs::set_permissions(&out_dir, original_permissions).unwrap(); + + output + .assert_exit_code(1) + .assert_stderr_contains("error: couldn't generate documentation: Permission denied"); +} diff --git a/tests/run-make/symlinked-libraries/rmake.rs b/tests/run-make/symlinked-libraries/rmake.rs index eaf0c44206a..3f02f19ccd5 100644 --- a/tests/run-make/symlinked-libraries/rmake.rs +++ b/tests/run-make/symlinked-libraries/rmake.rs @@ -6,6 +6,7 @@ // See https://github.com/rust-lang/rust/issues/12459 //@ ignore-cross-compile + use run_make_support::{create_symlink, dynamic_lib_name, fs_wrapper, rustc}; fn main() { diff --git a/tests/rustdoc-ui/doctest/auxiliary/pub_trait.rs b/tests/rustdoc-ui/doctest/auxiliary/pub_trait.rs new file mode 100644 index 00000000000..0a47fdc74d7 --- /dev/null +++ b/tests/rustdoc-ui/doctest/auxiliary/pub_trait.rs @@ -0,0 +1 @@ +pub trait Trait {} diff --git a/tests/rustdoc-ui/doctest/non-local-defs-impl.rs b/tests/rustdoc-ui/doctest/non-local-defs-impl.rs new file mode 100644 index 00000000000..c984e097c04 --- /dev/null +++ b/tests/rustdoc-ui/doctest/non-local-defs-impl.rs @@ -0,0 +1,31 @@ +//@ check-fail +//@ edition:2018 +//@ failure-status: 101 +//@ aux-build:pub_trait.rs +//@ compile-flags: --test --test-args --test-threads=1 +//@ normalize-stdout-test: "tests/rustdoc-ui/doctest" -> "$$DIR" +//@ normalize-stdout-test "finished in \d+\.\d+s" -> "finished in $$TIME" + +#![doc(test(attr(deny(non_local_definitions))))] +#![doc(test(attr(allow(dead_code))))] + +/// This will produce a warning: +/// ```rust,no_run +/// # extern crate pub_trait; +/// # use pub_trait::Trait; +/// +/// struct Local; +/// impl Trait for &Local {} +/// ``` +/// +/// But this shoudln't produce a warning: +/// ```rust,no_run +/// # extern crate pub_trait; +/// # use pub_trait::Trait; +/// +/// struct Local; +/// impl Trait for &Local {} +/// +/// # fn main() {} +/// ``` +pub fn doctest() {} diff --git a/tests/rustdoc-ui/doctest/non-local-defs-impl.stdout b/tests/rustdoc-ui/doctest/non-local-defs-impl.stdout new file mode 100644 index 00000000000..27797e22f8e --- /dev/null +++ b/tests/rustdoc-ui/doctest/non-local-defs-impl.stdout @@ -0,0 +1,37 @@ + +running 2 tests +test $DIR/non-local-defs-impl.rs - doctest (line 13) - compile ... FAILED +test $DIR/non-local-defs-impl.rs - doctest (line 22) - compile ... ok + +failures: + +---- $DIR/non-local-defs-impl.rs - doctest (line 13) stdout ---- +error: non-local `impl` definition, `impl` blocks should be written at the same level as their item + --> $DIR/non-local-defs-impl.rs:18:1 + | +LL | impl Trait for &Local {} + | ^^^^^-----^^^^^------ + | | | + | | `&'_ Local` is not local + | | help: remove `&` to make the `impl` local + | `Trait` is not local + | + = note: `impl` may be usable in bounds, etc. from outside the expression, which might e.g. make something constructible that previously wasn't, because it's still on a publicly-visible type + = note: an `impl` is never scoped, even when it is nested inside an item, as it may impact type checking outside of that item, which can be the case if neither the trait or the self type are at the same nesting level as the `impl` + = help: make this doc-test a standalone test with its own `fn main() { ... }` + = note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue <https://github.com/rust-lang/rust/issues/120363> +note: the lint level is defined here + --> $DIR/non-local-defs-impl.rs:11:9 + | +LL | #![deny(non_local_definitions)] + | ^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 1 previous error + +Couldn't compile the test. + +failures: + $DIR/non-local-defs-impl.rs - doctest (line 13) + +test result: FAILED. 1 passed; 1 failed; 0 ignored; 0 measured; 0 filtered out; finished in $TIME + diff --git a/tests/ui/asm/aarch64/may_unwind.rs b/tests/ui/asm/aarch64/may_unwind.rs index a483008c364..01d52f9022d 100644 --- a/tests/ui/asm/aarch64/may_unwind.rs +++ b/tests/ui/asm/aarch64/may_unwind.rs @@ -16,7 +16,7 @@ impl Drop for Foo<'_> { } } -extern "C" fn panicky() { +extern "C-unwind" fn panicky() { resume_unwind(Box::new(())); } diff --git a/tests/ui/asm/x86_64/may_unwind.rs b/tests/ui/asm/x86_64/may_unwind.rs index 3b2c1edcd47..d3a2916df9d 100644 --- a/tests/ui/asm/x86_64/may_unwind.rs +++ b/tests/ui/asm/x86_64/may_unwind.rs @@ -16,7 +16,7 @@ impl Drop for Foo<'_> { } } -extern "C" fn panicky() { +extern "C-unwind" fn panicky() { resume_unwind(Box::new(())); } diff --git a/tests/ui/async-await/async-closures/wrong-fn-kind.stderr b/tests/ui/async-await/async-closures/wrong-fn-kind.stderr index e56389b3202..6f07a6feed3 100644 --- a/tests/ui/async-await/async-closures/wrong-fn-kind.stderr +++ b/tests/ui/async-await/async-closures/wrong-fn-kind.stderr @@ -20,15 +20,16 @@ LL | fn needs_async_fn(_: impl async Fn()) {} | ^^^^^^^^^^ required by this bound in `needs_async_fn` error[E0596]: cannot borrow `x` as mutable, as it is a captured variable in a `Fn` closure - --> $DIR/wrong-fn-kind.rs:9:29 + --> $DIR/wrong-fn-kind.rs:9:20 | LL | fn needs_async_fn(_: impl async Fn()) {} | --------------- change this to accept `FnMut` instead of `Fn` ... LL | needs_async_fn(async || { - | _____--------------_--------_^ - | | | | - | | | in this closure + | -------------- ^------- + | | | + | _____|______________in this closure + | | | | | expects `Fn` instead of `FnMut` LL | | LL | | x += 1; diff --git a/tests/ui/check-cfg/mix.stderr b/tests/ui/check-cfg/mix.stderr index b3d0046fc17..cc63466585a 100644 --- a/tests/ui/check-cfg/mix.stderr +++ b/tests/ui/check-cfg/mix.stderr @@ -251,7 +251,7 @@ warning: unexpected `cfg` condition value: `zebra` LL | cfg!(target_feature = "zebra"); | ^^^^^^^^^^^^^^^^^^^^^^^^ | - = note: expected values for `target_feature` are: `10e60`, `2e3`, `3e3r1`, `3e3r2`, `3e3r3`, `3e7`, `7e10`, `a`, `aclass`, `adx`, `aes`, `altivec`, `alu32`, `atomics`, `avx`, `avx2`, `avx512bf16`, `avx512bitalg`, `avx512bw`, `avx512cd`, `avx512dq`, `avx512f`, `avx512fp16`, `avx512ifma`, `avx512vbmi`, `avx512vbmi2`, `avx512vl`, `avx512vnni`, `avx512vp2intersect`, `avx512vpopcntdq`, `bf16`, `bmi1`, `bmi2`, `bti`, and `bulk-memory` and 186 more + = note: expected values for `target_feature` are: `10e60`, `2e3`, `3e3r1`, `3e3r2`, `3e3r3`, `3e7`, `7e10`, `a`, `aclass`, `adx`, `aes`, `altivec`, `alu32`, `atomics`, `avx`, `avx2`, `avx512bf16`, `avx512bitalg`, `avx512bw`, `avx512cd`, `avx512dq`, `avx512f`, `avx512fp16`, `avx512ifma`, `avx512vbmi`, `avx512vbmi2`, `avx512vl`, `avx512vnni`, `avx512vp2intersect`, `avx512vpopcntdq`, `avxifma`, `avxneconvert`, `avxvnni`, `avxvnniint16`, and `avxvnniint8` and 191 more = note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration warning: 27 warnings emitted diff --git a/tests/ui/check-cfg/well-known-values.stderr b/tests/ui/check-cfg/well-known-values.stderr index d2026a68450..8a99ace75d8 100644 --- a/tests/ui/check-cfg/well-known-values.stderr +++ b/tests/ui/check-cfg/well-known-values.stderr @@ -165,7 +165,7 @@ warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE` LL | target_feature = "_UNEXPECTED_VALUE", | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = note: expected values for `target_feature` are: `10e60`, `2e3`, `3e3r1`, `3e3r2`, `3e3r3`, `3e7`, `7e10`, `a`, `aclass`, `adx`, `aes`, `altivec`, `alu32`, `atomics`, `avx`, `avx2`, `avx512bf16`, `avx512bitalg`, `avx512bw`, `avx512cd`, `avx512dq`, `avx512f`, `avx512fp16`, `avx512ifma`, `avx512vbmi`, `avx512vbmi2`, `avx512vl`, `avx512vnni`, `avx512vp2intersect`, `avx512vpopcntdq`, `bf16`, `bmi1`, `bmi2`, `bti`, `bulk-memory`, `c`, `cache`, `cmpxchg16b`, `crc`, `crt-static`, `d`, `d32`, `dit`, `doloop`, `dotprod`, `dpb`, `dpb2`, `dsp`, `dsp1e2`, `dspe60`, `e`, `e1`, `e2`, `edsp`, `elrw`, `ermsb`, `exception-handling`, `extended-const`, `f`, `f16c`, `f32mm`, `f64mm`, `fcma`, `fdivdu`, `fhm`, `flagm`, `float1e2`, `float1e3`, `float3e4`, `float7e60`, `floate1`, `fma`, `fp-armv8`, `fp16`, `fp64`, `fpuv2_df`, `fpuv2_sf`, `fpuv3_df`, `fpuv3_hf`, `fpuv3_hi`, `fpuv3_sf`, `frecipe`, `frintts`, `fxsr`, `gfni`, `hard-float`, `hard-float-abi`, `hard-tp`, `high-registers`, `hvx`, `hvx-length128b`, `hwdiv`, `i8mm`, `jsconv`, `lahfsahf`, `lasx`, `lbt`, `lor`, `lse`, `lsx`, `lvz`, `lzcnt`, `m`, `mclass`, `movbe`, `mp`, `mp1e2`, `msa`, `mte`, `multivalue`, `mutable-globals`, `neon`, `nontrapping-fptoint`, `nvic`, `paca`, `pacg`, `pan`, `pclmulqdq`, `pmuv3`, `popcnt`, `power10-vector`, `power8-altivec`, `power8-vector`, `power9-altivec`, `power9-vector`, `prfchw`, `rand`, `ras`, `rclass`, `rcpc`, `rcpc2`, `rdm`, `rdrand`, `rdseed`, `reference-types`, `relax`, `relaxed-simd`, `rtm`, `sb`, `sha`, `sha2`, `sha3`, `sign-ext`, `simd128`, `sm4`, `spe`, `ssbs`, `sse`, `sse2`, `sse3`, `sse4.1`, `sse4.2`, `sse4a`, `ssse3`, `sve`, `sve2`, `sve2-aes`, `sve2-bitperm`, `sve2-sha3`, `sve2-sm4`, `tbm`, `thumb-mode`, `thumb2`, `tme`, `trust`, `trustzone`, `ual`, `unaligned-scalar-mem`, `v`, `v5te`, `v6`, `v6k`, `v6t2`, `v7`, `v8`, `v8.1a`, `v8.2a`, `v8.3a`, `v8.4a`, `v8.5a`, `v8.6a`, `v8.7a`, `vaes`, `vdsp2e60f`, `vdspv1`, `vdspv2`, `vfp2`, `vfp3`, `vfp4`, `vh`, `virt`, `virtualization`, `vpclmulqdq`, `vsx`, `xsave`, `xsavec`, `xsaveopt`, `xsaves`, `zba`, `zbb`, `zbc`, `zbkb`, `zbkc`, `zbkx`, `zbs`, `zdinx`, `zfh`, `zfhmin`, `zfinx`, `zhinx`, `zhinxmin`, `zk`, `zkn`, `zknd`, `zkne`, `zknh`, `zkr`, `zks`, `zksed`, `zksh`, and `zkt` + = note: expected values for `target_feature` are: `10e60`, `2e3`, `3e3r1`, `3e3r2`, `3e3r3`, `3e7`, `7e10`, `a`, `aclass`, `adx`, `aes`, `altivec`, `alu32`, `atomics`, `avx`, `avx2`, `avx512bf16`, `avx512bitalg`, `avx512bw`, `avx512cd`, `avx512dq`, `avx512f`, `avx512fp16`, `avx512ifma`, `avx512vbmi`, `avx512vbmi2`, `avx512vl`, `avx512vnni`, `avx512vp2intersect`, `avx512vpopcntdq`, `avxifma`, `avxneconvert`, `avxvnni`, `avxvnniint16`, `avxvnniint8`, `bf16`, `bmi1`, `bmi2`, `bti`, `bulk-memory`, `c`, `cache`, `cmpxchg16b`, `crc`, `crt-static`, `d`, `d32`, `dit`, `doloop`, `dotprod`, `dpb`, `dpb2`, `dsp`, `dsp1e2`, `dspe60`, `e`, `e1`, `e2`, `edsp`, `elrw`, `ermsb`, `exception-handling`, `extended-const`, `f`, `f16c`, `f32mm`, `f64mm`, `fcma`, `fdivdu`, `fhm`, `flagm`, `float1e2`, `float1e3`, `float3e4`, `float7e60`, `floate1`, `fma`, `fp-armv8`, `fp16`, `fp64`, `fpuv2_df`, `fpuv2_sf`, `fpuv3_df`, `fpuv3_hf`, `fpuv3_hi`, `fpuv3_sf`, `frecipe`, `frintts`, `fxsr`, `gfni`, `hard-float`, `hard-float-abi`, `hard-tp`, `high-registers`, `hvx`, `hvx-length128b`, `hwdiv`, `i8mm`, `jsconv`, `lahfsahf`, `lasx`, `lbt`, `lor`, `lse`, `lsx`, `lvz`, `lzcnt`, `m`, `mclass`, `movbe`, `mp`, `mp1e2`, `msa`, `mte`, `multivalue`, `mutable-globals`, `neon`, `nontrapping-fptoint`, `nvic`, `paca`, `pacg`, `pan`, `pclmulqdq`, `pmuv3`, `popcnt`, `power10-vector`, `power8-altivec`, `power8-vector`, `power9-altivec`, `power9-vector`, `prfchw`, `rand`, `ras`, `rclass`, `rcpc`, `rcpc2`, `rdm`, `rdrand`, `rdseed`, `reference-types`, `relax`, `relaxed-simd`, `rtm`, `sb`, `sha`, `sha2`, `sha3`, `sign-ext`, `simd128`, `sm4`, `spe`, `ssbs`, `sse`, `sse2`, `sse3`, `sse4.1`, `sse4.2`, `sse4a`, `ssse3`, `sve`, `sve2`, `sve2-aes`, `sve2-bitperm`, `sve2-sha3`, `sve2-sm4`, `tbm`, `thumb-mode`, `thumb2`, `tme`, `trust`, `trustzone`, `ual`, `unaligned-scalar-mem`, `v`, `v5te`, `v6`, `v6k`, `v6t2`, `v7`, `v8`, `v8.1a`, `v8.2a`, `v8.3a`, `v8.4a`, `v8.5a`, `v8.6a`, `v8.7a`, `vaes`, `vdsp2e60f`, `vdspv1`, `vdspv2`, `vfp2`, `vfp3`, `vfp4`, `vh`, `virt`, `virtualization`, `vpclmulqdq`, `vsx`, `xsave`, `xsavec`, `xsaveopt`, `xsaves`, `zba`, `zbb`, `zbc`, `zbkb`, `zbkc`, `zbkx`, `zbs`, `zdinx`, `zfh`, `zfhmin`, `zfinx`, `zhinx`, `zhinxmin`, `zk`, `zkn`, `zknd`, `zkne`, `zknh`, `zkr`, `zks`, `zksed`, `zksh`, and `zkt` = note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE` diff --git a/tests/ui/coherence/occurs-check/associated-type.next.stderr b/tests/ui/coherence/occurs-check/associated-type.next.stderr index bd65cee58d9..4f15be4c7c8 100644 --- a/tests/ui/coherence/occurs-check/associated-type.next.stderr +++ b/tests/ui/coherence/occurs-check/associated-type.next.stderr @@ -1,7 +1,7 @@ - WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: AliasTy { args: [*const ?1t, '^0.Named(DefId(0:27 ~ associated_type[f554]::{impl#3}::'a#1), "'a")], def_id: DefId(0:5 ~ associated_type[f554]::ToUnit::Unit), _use_alias_ty_new_instead: () } - WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: AliasTy { args: [*const ?1t, '^0.Named(DefId(0:27 ~ associated_type[f554]::{impl#3}::'a#1), "'a")], def_id: DefId(0:5 ~ associated_type[f554]::ToUnit::Unit), _use_alias_ty_new_instead: () } - WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: AliasTy { args: [*const ?1t, '^0.Named(DefId(0:27 ~ associated_type[f554]::{impl#3}::'a#1), "'a")], def_id: DefId(0:5 ~ associated_type[f554]::ToUnit::Unit), _use_alias_ty_new_instead: () } - WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: AliasTy { args: [*const ?1t, '^0.Named(DefId(0:27 ~ associated_type[f554]::{impl#3}::'a#1), "'a")], def_id: DefId(0:5 ~ associated_type[f554]::ToUnit::Unit), _use_alias_ty_new_instead: () } + WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: AliasTy { args: [*const ?1t, '^0.Named(DefId(0:27 ~ associated_type[f554]::{impl#3}::'a#1), "'a")], def_id: DefId(0:5 ~ associated_type[f554]::ToUnit::Unit) } + WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: AliasTy { args: [*const ?1t, '^0.Named(DefId(0:27 ~ associated_type[f554]::{impl#3}::'a#1), "'a")], def_id: DefId(0:5 ~ associated_type[f554]::ToUnit::Unit) } + WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: AliasTy { args: [*const ?1t, '^0.Named(DefId(0:27 ~ associated_type[f554]::{impl#3}::'a#1), "'a")], def_id: DefId(0:5 ~ associated_type[f554]::ToUnit::Unit) } + WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: AliasTy { args: [*const ?1t, '^0.Named(DefId(0:27 ~ associated_type[f554]::{impl#3}::'a#1), "'a")], def_id: DefId(0:5 ~ associated_type[f554]::ToUnit::Unit) } error[E0119]: conflicting implementations of trait `Overlap<for<'a> fn(&'a (), ())>` for type `for<'a> fn(&'a (), ())` --> $DIR/associated-type.rs:31:1 | diff --git a/tests/ui/coherence/occurs-check/associated-type.old.stderr b/tests/ui/coherence/occurs-check/associated-type.old.stderr index d26f7665ee7..329086ab7df 100644 --- a/tests/ui/coherence/occurs-check/associated-type.old.stderr +++ b/tests/ui/coherence/occurs-check/associated-type.old.stderr @@ -1,11 +1,11 @@ - WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: AliasTy { args: [*const ?1t, '^0.Named(DefId(0:27 ~ associated_type[f554]::{impl#3}::'a#1), "'a")], def_id: DefId(0:5 ~ associated_type[f554]::ToUnit::Unit), _use_alias_ty_new_instead: () } - WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: AliasTy { args: [*const ?1t, !2_0.Named(DefId(0:27 ~ associated_type[f554]::{impl#3}::'a#1), "'a")], def_id: DefId(0:5 ~ associated_type[f554]::ToUnit::Unit), _use_alias_ty_new_instead: () } - WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: AliasTy { args: [*const ?1t, '^0.Named(DefId(0:27 ~ associated_type[f554]::{impl#3}::'a#1), "'a")], def_id: DefId(0:5 ~ associated_type[f554]::ToUnit::Unit), _use_alias_ty_new_instead: () } - WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: AliasTy { args: [*const ?1t, !2_0.Named(DefId(0:27 ~ associated_type[f554]::{impl#3}::'a#1), "'a")], def_id: DefId(0:5 ~ associated_type[f554]::ToUnit::Unit), _use_alias_ty_new_instead: () } - WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: AliasTy { args: [*const ?1t, '^0.Named(DefId(0:27 ~ associated_type[f554]::{impl#3}::'a#1), "'a")], def_id: DefId(0:5 ~ associated_type[f554]::ToUnit::Unit), _use_alias_ty_new_instead: () } - WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: AliasTy { args: [*const ?1t, !2_0.Named(DefId(0:27 ~ associated_type[f554]::{impl#3}::'a#1), "'a")], def_id: DefId(0:5 ~ associated_type[f554]::ToUnit::Unit), _use_alias_ty_new_instead: () } - WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: AliasTy { args: [*const ?1t, '^0.Named(DefId(0:27 ~ associated_type[f554]::{impl#3}::'a#1), "'a")], def_id: DefId(0:5 ~ associated_type[f554]::ToUnit::Unit), _use_alias_ty_new_instead: () } - WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: AliasTy { args: [*const ?1t, !2_0.Named(DefId(0:27 ~ associated_type[f554]::{impl#3}::'a#1), "'a")], def_id: DefId(0:5 ~ associated_type[f554]::ToUnit::Unit), _use_alias_ty_new_instead: () } + WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: AliasTy { args: [*const ?1t, '^0.Named(DefId(0:27 ~ associated_type[f554]::{impl#3}::'a#1), "'a")], def_id: DefId(0:5 ~ associated_type[f554]::ToUnit::Unit) } + WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: AliasTy { args: [*const ?1t, !2_0.Named(DefId(0:27 ~ associated_type[f554]::{impl#3}::'a#1), "'a")], def_id: DefId(0:5 ~ associated_type[f554]::ToUnit::Unit) } + WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: AliasTy { args: [*const ?1t, '^0.Named(DefId(0:27 ~ associated_type[f554]::{impl#3}::'a#1), "'a")], def_id: DefId(0:5 ~ associated_type[f554]::ToUnit::Unit) } + WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: AliasTy { args: [*const ?1t, !2_0.Named(DefId(0:27 ~ associated_type[f554]::{impl#3}::'a#1), "'a")], def_id: DefId(0:5 ~ associated_type[f554]::ToUnit::Unit) } + WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: AliasTy { args: [*const ?1t, '^0.Named(DefId(0:27 ~ associated_type[f554]::{impl#3}::'a#1), "'a")], def_id: DefId(0:5 ~ associated_type[f554]::ToUnit::Unit) } + WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: AliasTy { args: [*const ?1t, !2_0.Named(DefId(0:27 ~ associated_type[f554]::{impl#3}::'a#1), "'a")], def_id: DefId(0:5 ~ associated_type[f554]::ToUnit::Unit) } + WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: AliasTy { args: [*const ?1t, '^0.Named(DefId(0:27 ~ associated_type[f554]::{impl#3}::'a#1), "'a")], def_id: DefId(0:5 ~ associated_type[f554]::ToUnit::Unit) } + WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: AliasTy { args: [*const ?1t, !2_0.Named(DefId(0:27 ~ associated_type[f554]::{impl#3}::'a#1), "'a")], def_id: DefId(0:5 ~ associated_type[f554]::ToUnit::Unit) } error[E0119]: conflicting implementations of trait `Overlap<for<'a> fn(&'a (), _)>` for type `for<'a> fn(&'a (), _)` --> $DIR/associated-type.rs:31:1 | diff --git a/tests/ui/const-generics/defaults/doesnt_infer.rs b/tests/ui/const-generics/defaults/doesnt_infer.rs index 016685eee9d..f62088210fe 100644 --- a/tests/ui/const-generics/defaults/doesnt_infer.rs +++ b/tests/ui/const-generics/defaults/doesnt_infer.rs @@ -12,4 +12,5 @@ fn main() { let foo = Foo::<1>::foo(); let foo = Foo::foo(); //~^ ERROR type annotations needed for `Foo<_>` + //~| ERROR type annotations needed } diff --git a/tests/ui/const-generics/defaults/doesnt_infer.stderr b/tests/ui/const-generics/defaults/doesnt_infer.stderr index 1e779f75ce0..c17f57f36bc 100644 --- a/tests/ui/const-generics/defaults/doesnt_infer.stderr +++ b/tests/ui/const-generics/defaults/doesnt_infer.stderr @@ -1,14 +1,37 @@ -error[E0282]: type annotations needed for `Foo<_>` +error[E0284]: type annotations needed for `Foo<_>` --> $DIR/doesnt_infer.rs:13:9 | LL | let foo = Foo::foo(); - | ^^^ + | ^^^ ---------- type must be known at this point | +note: required by a const generic parameter in `Foo::<N>::foo` + --> $DIR/doesnt_infer.rs:5:6 + | +LL | impl<const N: u32> Foo<N> { + | ^^^^^^^^^^^^ required by this const generic parameter in `Foo::<N>::foo` +LL | fn foo() -> Self { + | --- required by a bound in this associated function +help: consider giving `foo` an explicit type, where the value of const parameter `N` is specified + | +LL | let foo: Foo<N> = Foo::foo(); + | ++++++++ + +error[E0284]: type annotations needed for `Foo<_>` + --> $DIR/doesnt_infer.rs:13:9 + | +LL | let foo = Foo::foo(); + | ^^^ --- type must be known at this point + | +note: required by a const generic parameter in `Foo` + --> $DIR/doesnt_infer.rs:3:12 + | +LL | struct Foo<const N: u32 = 2>; + | ^^^^^^^^^^^^^^^^ required by this const generic parameter in `Foo` help: consider giving `foo` an explicit type, where the value of const parameter `N` is specified | LL | let foo: Foo<N> = Foo::foo(); | ++++++++ -error: aborting due to 1 previous error +error: aborting due to 2 previous errors -For more information about this error, try `rustc --explain E0282`. +For more information about this error, try `rustc --explain E0284`. diff --git a/tests/ui/const-generics/defaults/rp_impl_trait_fail.stderr b/tests/ui/const-generics/defaults/rp_impl_trait_fail.stderr index 4ed1c0ded9f..45be3126e3b 100644 --- a/tests/ui/const-generics/defaults/rp_impl_trait_fail.stderr +++ b/tests/ui/const-generics/defaults/rp_impl_trait_fail.stderr @@ -31,12 +31,17 @@ LL | 1_u64 | = help: the trait `Traitor<1, 2>` is implemented for `u64` -error[E0282]: type annotations needed +error[E0284]: type annotations needed --> $DIR/rp_impl_trait_fail.rs:28:5 | LL | uwu(); | ^^^ cannot infer the value of the const parameter `N` declared on the function `uwu` | +note: required by a const generic parameter in `uwu` + --> $DIR/rp_impl_trait_fail.rs:16:8 + | +LL | fn uwu<const N: u8>() -> impl Traitor<N> { + | ^^^^^^^^^^^ required by this const generic parameter in `uwu` help: consider specifying the generic argument | LL | uwu::<N>(); @@ -44,5 +49,5 @@ LL | uwu::<N>(); error: aborting due to 4 previous errors -Some errors have detailed explanations: E0277, E0282. +Some errors have detailed explanations: E0277, E0284. For more information about an error, try `rustc --explain E0277`. diff --git a/tests/ui/const-generics/generic_arg_infer/issue-91614.rs b/tests/ui/const-generics/generic_arg_infer/issue-91614.rs index cfbc5faecd9..a386b1e5c2b 100644 --- a/tests/ui/const-generics/generic_arg_infer/issue-91614.rs +++ b/tests/ui/const-generics/generic_arg_infer/issue-91614.rs @@ -5,4 +5,5 @@ use std::simd::Mask; fn main() { let y = Mask::<_, _>::splat(false); //~^ ERROR: type annotations needed + //~| ERROR type annotations needed } diff --git a/tests/ui/const-generics/generic_arg_infer/issue-91614.stderr b/tests/ui/const-generics/generic_arg_infer/issue-91614.stderr index 563406ad5ea..217f609459e 100644 --- a/tests/ui/const-generics/generic_arg_infer/issue-91614.stderr +++ b/tests/ui/const-generics/generic_arg_infer/issue-91614.stderr @@ -1,23 +1,29 @@ -error[E0283]: type annotations needed for `Mask<_, _>` +error[E0284]: type annotations needed for `Mask<_, _>` --> $DIR/issue-91614.rs:6:9 | LL | let y = Mask::<_, _>::splat(false); | ^ -------------------------- type must be known at this point | - = note: cannot satisfy `_: MaskElement` - = help: the following types implement trait `MaskElement`: - i16 - i32 - i64 - i8 - isize -note: required by a bound in `Mask::<T, N>::splat` +note: required by a const generic parameter in `Mask::<T, N>::splat` --> $SRC_DIR/core/src/../../portable-simd/crates/core_simd/src/masks.rs:LL:COL -help: consider giving `y` an explicit type, where the type for type parameter `T` is specified +help: consider giving `y` an explicit type, where the value of const parameter `N` is specified | LL | let y: Mask<T, N> = Mask::<_, _>::splat(false); | ++++++++++++ -error: aborting due to 1 previous error +error[E0284]: type annotations needed for `Mask<_, _>` + --> $DIR/issue-91614.rs:6:9 + | +LL | let y = Mask::<_, _>::splat(false); + | ^ ------------ type must be known at this point + | +note: required by a const generic parameter in `Mask` + --> $SRC_DIR/core/src/../../portable-simd/crates/core_simd/src/masks.rs:LL:COL +help: consider giving `y` an explicit type, where the value of const parameter `N` is specified + | +LL | let y: Mask<T, N> = Mask::<_, _>::splat(false); + | ++++++++++++ + +error: aborting due to 2 previous errors -For more information about this error, try `rustc --explain E0283`. +For more information about this error, try `rustc --explain E0284`. diff --git a/tests/ui/const-generics/generic_const_exprs/issue-62504.full.stderr b/tests/ui/const-generics/generic_const_exprs/issue-62504.full.stderr index 5cda4681b5c..3739637c279 100644 --- a/tests/ui/const-generics/generic_const_exprs/issue-62504.full.stderr +++ b/tests/ui/const-generics/generic_const_exprs/issue-62504.full.stderr @@ -18,18 +18,41 @@ help: try adding a `where` bound LL | pub const fn new() -> Self where [(); Self::SIZE]: { | +++++++++++++++++++++++ -error[E0282]: type annotations needed for `ArrayHolder<_>` +error[E0284]: type annotations needed for `ArrayHolder<_>` --> $DIR/issue-62504.rs:26:9 | LL | let mut array = ArrayHolder::new(); - | ^^^^^^^^^ + | ^^^^^^^^^ ------------------ type must be known at this point | +note: required by a const generic parameter in `ArrayHolder::<X>::new` + --> $DIR/issue-62504.rs:16:6 + | +LL | impl<const X: usize> ArrayHolder<X> { + | ^^^^^^^^^^^^^^ required by this const generic parameter in `ArrayHolder::<X>::new` +LL | pub const fn new() -> Self { + | --- required by a bound in this associated function +help: consider giving `array` an explicit type, where the value of const parameter `X` is specified + | +LL | let mut array: ArrayHolder<X> = ArrayHolder::new(); + | ++++++++++++++++ + +error[E0284]: type annotations needed for `ArrayHolder<_>` + --> $DIR/issue-62504.rs:26:9 + | +LL | let mut array = ArrayHolder::new(); + | ^^^^^^^^^ ----------- type must be known at this point + | +note: required by a const generic parameter in `ArrayHolder` + --> $DIR/issue-62504.rs:14:20 + | +LL | struct ArrayHolder<const X: usize>([u32; X]); + | ^^^^^^^^^^^^^^ required by this const generic parameter in `ArrayHolder` help: consider giving `array` an explicit type, where the value of const parameter `X` is specified | LL | let mut array: ArrayHolder<X> = ArrayHolder::new(); | ++++++++++++++++ -error: aborting due to 3 previous errors +error: aborting due to 4 previous errors -Some errors have detailed explanations: E0282, E0308. -For more information about an error, try `rustc --explain E0282`. +Some errors have detailed explanations: E0284, E0308. +For more information about an error, try `rustc --explain E0284`. diff --git a/tests/ui/const-generics/generic_const_exprs/issue-62504.min.stderr b/tests/ui/const-generics/generic_const_exprs/issue-62504.min.stderr index beb159779ff..14c67e2528a 100644 --- a/tests/ui/const-generics/generic_const_exprs/issue-62504.min.stderr +++ b/tests/ui/const-generics/generic_const_exprs/issue-62504.min.stderr @@ -22,18 +22,41 @@ note: tuple struct defined here LL | struct ArrayHolder<const X: usize>([u32; X]); | ^^^^^^^^^^^ -error[E0282]: type annotations needed for `ArrayHolder<_>` +error[E0284]: type annotations needed for `ArrayHolder<_>` --> $DIR/issue-62504.rs:26:9 | LL | let mut array = ArrayHolder::new(); - | ^^^^^^^^^ + | ^^^^^^^^^ ------------------ type must be known at this point | +note: required by a const generic parameter in `ArrayHolder::<X>::new` + --> $DIR/issue-62504.rs:16:6 + | +LL | impl<const X: usize> ArrayHolder<X> { + | ^^^^^^^^^^^^^^ required by this const generic parameter in `ArrayHolder::<X>::new` +LL | pub const fn new() -> Self { + | --- required by a bound in this associated function +help: consider giving `array` an explicit type, where the value of const parameter `X` is specified + | +LL | let mut array: ArrayHolder<X> = ArrayHolder::new(); + | ++++++++++++++++ + +error[E0284]: type annotations needed for `ArrayHolder<_>` + --> $DIR/issue-62504.rs:26:9 + | +LL | let mut array = ArrayHolder::new(); + | ^^^^^^^^^ ----------- type must be known at this point + | +note: required by a const generic parameter in `ArrayHolder` + --> $DIR/issue-62504.rs:14:20 + | +LL | struct ArrayHolder<const X: usize>([u32; X]); + | ^^^^^^^^^^^^^^ required by this const generic parameter in `ArrayHolder` help: consider giving `array` an explicit type, where the value of const parameter `X` is specified | LL | let mut array: ArrayHolder<X> = ArrayHolder::new(); | ++++++++++++++++ -error: aborting due to 3 previous errors +error: aborting due to 4 previous errors -Some errors have detailed explanations: E0282, E0308. -For more information about an error, try `rustc --explain E0282`. +Some errors have detailed explanations: E0284, E0308. +For more information about an error, try `rustc --explain E0284`. diff --git a/tests/ui/const-generics/generic_const_exprs/issue-62504.rs b/tests/ui/const-generics/generic_const_exprs/issue-62504.rs index b6a6a277843..f021e103614 100644 --- a/tests/ui/const-generics/generic_const_exprs/issue-62504.rs +++ b/tests/ui/const-generics/generic_const_exprs/issue-62504.rs @@ -25,4 +25,5 @@ impl<const X: usize> ArrayHolder<X> { fn main() { let mut array = ArrayHolder::new(); //~^ ERROR: type annotations needed + //~| ERROR type annotations needed } diff --git a/tests/ui/const-generics/generic_const_exprs/object-safety-ok-infer-err.rs b/tests/ui/const-generics/generic_const_exprs/object-safety-ok-infer-err.rs index 79e9834b54e..298cfb512e4 100644 --- a/tests/ui/const-generics/generic_const_exprs/object-safety-ok-infer-err.rs +++ b/tests/ui/const-generics/generic_const_exprs/object-safety-ok-infer-err.rs @@ -18,4 +18,5 @@ fn use_dyn<const N: usize>(v: &dyn Foo<N>) where [u8; N + 1]: Sized { fn main() { use_dyn(&()); //~^ ERROR type annotations needed + //~| ERROR type annotations needed } diff --git a/tests/ui/const-generics/generic_const_exprs/object-safety-ok-infer-err.stderr b/tests/ui/const-generics/generic_const_exprs/object-safety-ok-infer-err.stderr index e800c5d059f..d1e1c976da6 100644 --- a/tests/ui/const-generics/generic_const_exprs/object-safety-ok-infer-err.stderr +++ b/tests/ui/const-generics/generic_const_exprs/object-safety-ok-infer-err.stderr @@ -4,16 +4,37 @@ error[E0284]: type annotations needed LL | use_dyn(&()); | ^^^^^^^ cannot infer the value of the const parameter `N` declared on the function `use_dyn` | -note: required by a bound in `use_dyn` - --> $DIR/object-safety-ok-infer-err.rs:14:55 +note: required by a const generic parameter in `use_dyn` + --> $DIR/object-safety-ok-infer-err.rs:14:12 | LL | fn use_dyn<const N: usize>(v: &dyn Foo<N>) where [u8; N + 1]: Sized { - | ^^^^^ required by this bound in `use_dyn` + | ^^^^^^^^^^^^^^ required by this const generic parameter in `use_dyn` help: consider specifying the generic argument | LL | use_dyn::<N>(&()); | +++++ -error: aborting due to 1 previous error +error[E0284]: type annotations needed + --> $DIR/object-safety-ok-infer-err.rs:19:5 + | +LL | use_dyn(&()); + | ^^^^^^^ --- type must be known at this point + | | + | cannot infer the value of the const parameter `N` declared on the function `use_dyn` + | +note: required for `()` to implement `Foo<_>` + --> $DIR/object-safety-ok-infer-err.rs:8:22 + | +LL | impl<const N: usize> Foo<N> for () { + | -------------- ^^^^^^ ^^ + | | + | unsatisfied trait bound introduced here + = note: required for the cast from `&()` to `&dyn Foo<_>` +help: consider specifying the generic argument + | +LL | use_dyn::<N>(&()); + | +++++ + +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0284`. diff --git a/tests/ui/const-generics/infer/cannot-infer-const-args.stderr b/tests/ui/const-generics/infer/cannot-infer-const-args.stderr index e3caefef10f..c349a50a83f 100644 --- a/tests/ui/const-generics/infer/cannot-infer-const-args.stderr +++ b/tests/ui/const-generics/infer/cannot-infer-const-args.stderr @@ -1,9 +1,14 @@ -error[E0282]: type annotations needed +error[E0284]: type annotations needed --> $DIR/cannot-infer-const-args.rs:6:5 | LL | foo(); | ^^^ cannot infer the value of the const parameter `X` declared on the function `foo` | +note: required by a const generic parameter in `foo` + --> $DIR/cannot-infer-const-args.rs:1:8 + | +LL | fn foo<const X: usize>() -> usize { + | ^^^^^^^^^^^^^^ required by this const generic parameter in `foo` help: consider specifying the generic argument | LL | foo::<X>(); @@ -11,4 +16,4 @@ LL | foo::<X>(); error: aborting due to 1 previous error -For more information about this error, try `rustc --explain E0282`. +For more information about this error, try `rustc --explain E0284`. diff --git a/tests/ui/const-generics/infer/issue-77092.rs b/tests/ui/const-generics/infer/issue-77092.rs index fcf7d3282b4..47c594e5b11 100644 --- a/tests/ui/const-generics/infer/issue-77092.rs +++ b/tests/ui/const-generics/infer/issue-77092.rs @@ -1,14 +1,15 @@ use std::convert::TryInto; fn take_array_from_mut<T, const N: usize>(data: &mut [T], start: usize) -> &mut [T; N] { - (&mut data[start .. start + N]).try_into().unwrap() + (&mut data[start..start + N]).try_into().unwrap() } fn main() { let mut arr = [0, 1, 2, 3, 4, 5, 6, 7, 8]; - for i in 1 .. 4 { + for i in 1..4 { println!("{:?}", take_array_from_mut(&mut arr, i)); //~^ ERROR type annotations needed + //~| ERROR type annotations needed } } diff --git a/tests/ui/const-generics/infer/issue-77092.stderr b/tests/ui/const-generics/infer/issue-77092.stderr index 5b411269862..9a6374a2adc 100644 --- a/tests/ui/const-generics/infer/issue-77092.stderr +++ b/tests/ui/const-generics/infer/issue-77092.stderr @@ -1,14 +1,37 @@ -error[E0282]: type annotations needed +error[E0284]: type annotations needed --> $DIR/issue-77092.rs:11:26 | LL | println!("{:?}", take_array_from_mut(&mut arr, i)); | ^^^^^^^^^^^^^^^^^^^ cannot infer the value of the const parameter `N` declared on the function `take_array_from_mut` | +note: required by a const generic parameter in `take_array_from_mut` + --> $DIR/issue-77092.rs:3:27 + | +LL | fn take_array_from_mut<T, const N: usize>(data: &mut [T], start: usize) -> &mut [T; N] { + | ^^^^^^^^^^^^^^ required by this const generic parameter in `take_array_from_mut` +help: consider specifying the generic arguments + | +LL | println!("{:?}", take_array_from_mut::<i32, N>(&mut arr, i)); + | ++++++++++ + +error[E0284]: type annotations needed + --> $DIR/issue-77092.rs:11:26 + | +LL | println!("{:?}", take_array_from_mut(&mut arr, i)); + | ---- ^^^^^^^^^^^^^^^^^^^ cannot infer the value of the const parameter `N` declared on the function `take_array_from_mut` + | | + | type must be known at this point + | + = note: required for `[i32; _]` to implement `Debug` + = note: 1 redundant requirement hidden + = note: required for `&mut [i32; _]` to implement `Debug` +note: required by a bound in `core::fmt::rt::Argument::<'a>::new_debug` + --> $SRC_DIR/core/src/fmt/rt.rs:LL:COL help: consider specifying the generic arguments | LL | println!("{:?}", take_array_from_mut::<i32, N>(&mut arr, i)); | ++++++++++ -error: aborting due to 1 previous error +error: aborting due to 2 previous errors -For more information about this error, try `rustc --explain E0282`. +For more information about this error, try `rustc --explain E0284`. diff --git a/tests/ui/const-generics/infer/method-chain.stderr b/tests/ui/const-generics/infer/method-chain.stderr index 2def9e85ab7..95044bb5203 100644 --- a/tests/ui/const-generics/infer/method-chain.stderr +++ b/tests/ui/const-generics/infer/method-chain.stderr @@ -1,9 +1,14 @@ -error[E0282]: type annotations needed +error[E0284]: type annotations needed --> $DIR/method-chain.rs:15:33 | LL | Foo.bar().bar().bar().bar().baz(); | ^^^ cannot infer the value of the const parameter `N` declared on the method `baz` | +note: required by a const generic parameter in `Foo::baz` + --> $DIR/method-chain.rs:8:12 + | +LL | fn baz<const N: usize>(self) -> Foo { + | ^^^^^^^^^^^^^^ required by this const generic parameter in `Foo::baz` help: consider specifying the generic argument | LL | Foo.bar().bar().bar().bar().baz::<N>(); @@ -11,4 +16,4 @@ LL | Foo.bar().bar().bar().bar().baz::<N>(); error: aborting due to 1 previous error -For more information about this error, try `rustc --explain E0282`. +For more information about this error, try `rustc --explain E0284`. diff --git a/tests/ui/const-generics/infer/one-param-uninferred.stderr b/tests/ui/const-generics/infer/one-param-uninferred.stderr index 3e33fec9cef..f3aa7973e67 100644 --- a/tests/ui/const-generics/infer/one-param-uninferred.stderr +++ b/tests/ui/const-generics/infer/one-param-uninferred.stderr @@ -1,9 +1,14 @@ -error[E0282]: type annotations needed +error[E0284]: type annotations needed --> $DIR/one-param-uninferred.rs:9:23 | LL | let _: [u8; 17] = foo(); | ^^^ cannot infer the value of the const parameter `M` declared on the function `foo` | +note: required by a const generic parameter in `foo` + --> $DIR/one-param-uninferred.rs:2:24 + | +LL | fn foo<const N: usize, const M: usize>() -> [u8; N] { + | ^^^^^^^^^^^^^^ required by this const generic parameter in `foo` help: consider specifying the generic arguments | LL | let _: [u8; 17] = foo::<17, M>(); @@ -11,4 +16,4 @@ LL | let _: [u8; 17] = foo::<17, M>(); error: aborting due to 1 previous error -For more information about this error, try `rustc --explain E0282`. +For more information about this error, try `rustc --explain E0284`. diff --git a/tests/ui/const-generics/infer/uninferred-consts.rs b/tests/ui/const-generics/infer/uninferred-consts.rs index 657f4b51304..552e2a15c23 100644 --- a/tests/ui/const-generics/infer/uninferred-consts.rs +++ b/tests/ui/const-generics/infer/uninferred-consts.rs @@ -8,4 +8,5 @@ impl Foo { fn main() { Foo.foo(); //~^ ERROR type annotations needed + //~| ERROR type annotations needed } diff --git a/tests/ui/const-generics/infer/uninferred-consts.stderr b/tests/ui/const-generics/infer/uninferred-consts.stderr index 0ec6ac9c22e..839fb25c4e1 100644 --- a/tests/ui/const-generics/infer/uninferred-consts.stderr +++ b/tests/ui/const-generics/infer/uninferred-consts.stderr @@ -1,14 +1,35 @@ -error[E0282]: type annotations needed +error[E0284]: type annotations needed --> $DIR/uninferred-consts.rs:9:9 | LL | Foo.foo(); | ^^^ cannot infer the value of the const parameter `A` declared on the method `foo` | +note: required by a const generic parameter in `Foo::foo` + --> $DIR/uninferred-consts.rs:6:12 + | +LL | fn foo<const A: usize, const B: usize>(self) {} + | ^^^^^^^^^^^^^^ required by this const generic parameter in `Foo::foo` +help: consider specifying the generic arguments + | +LL | Foo.foo::<A, B>(); + | ++++++++ + +error[E0284]: type annotations needed + --> $DIR/uninferred-consts.rs:9:9 + | +LL | Foo.foo(); + | ^^^ cannot infer the value of the const parameter `B` declared on the method `foo` + | +note: required by a const generic parameter in `Foo::foo` + --> $DIR/uninferred-consts.rs:6:28 + | +LL | fn foo<const A: usize, const B: usize>(self) {} + | ^^^^^^^^^^^^^^ required by this const generic parameter in `Foo::foo` help: consider specifying the generic arguments | LL | Foo.foo::<A, B>(); | ++++++++ -error: aborting due to 1 previous error +error: aborting due to 2 previous errors -For more information about this error, try `rustc --explain E0282`. +For more information about this error, try `rustc --explain E0284`. diff --git a/tests/crashes/125799.rs b/tests/ui/const-generics/mistyped_const_in_pat.rs index 62d5438b4e4..6f1dd52872f 100644 --- a/tests/crashes/125799.rs +++ b/tests/ui/const-generics/mistyped_const_in_pat.rs @@ -1,4 +1,5 @@ -//@ known-bug: rust-lang/rust#125799 +//! Used to ICE rust-lang/rust#125799 due to `isize` != `()` +//! not being detected early due to the conflicting impls. //@ only-x86_64 trait Trait<T> { @@ -10,6 +11,7 @@ impl<T> Trait<T> for Vec<T> { } impl Trait<u8> for Vec<u8> {} +//~^ ERROR: conflicting implementations const BAR: <Vec<u8> as Trait<u8>>::Assoc = 3; diff --git a/tests/ui/const-generics/mistyped_const_in_pat.stderr b/tests/ui/const-generics/mistyped_const_in_pat.stderr new file mode 100644 index 00000000000..de7516fa37f --- /dev/null +++ b/tests/ui/const-generics/mistyped_const_in_pat.stderr @@ -0,0 +1,12 @@ +error[E0119]: conflicting implementations of trait `Trait<u8>` for type `Vec<u8>` + --> $DIR/mistyped_const_in_pat.rs:13:1 + | +LL | impl<T> Trait<T> for Vec<T> { + | --------------------------- first implementation here +... +LL | impl Trait<u8> for Vec<u8> {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `Vec<u8>` + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0119`. diff --git a/tests/ui/const-generics/parent_generics_of_encoding_impl_trait.stderr b/tests/ui/const-generics/parent_generics_of_encoding_impl_trait.stderr index 5bef6f3c795..4809f7d37dd 100644 --- a/tests/ui/const-generics/parent_generics_of_encoding_impl_trait.stderr +++ b/tests/ui/const-generics/parent_generics_of_encoding_impl_trait.stderr @@ -4,11 +4,11 @@ error[E0284]: type annotations needed LL | generics_of_parent_impl_trait::foo([()]); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot infer the value of const parameter `N` declared on the function `foo` | -note: required by a bound in `foo` - --> $DIR/auxiliary/generics_of_parent_impl_trait.rs:5:48 +note: required by a const generic parameter in `foo` + --> $DIR/auxiliary/generics_of_parent_impl_trait.rs:5:12 | LL | pub fn foo<const N: usize>(foo: impl Into<[(); N + 1]>) { - | ^^^^^ required by this bound in `foo` + | ^^^^^^^^^^^^^^ required by this const generic parameter in `foo` error: aborting due to 1 previous error diff --git a/tests/ui/const-generics/type_mismatch.stderr b/tests/ui/const-generics/type_mismatch.stderr index 07476ae76c6..026999827c0 100644 --- a/tests/ui/const-generics/type_mismatch.stderr +++ b/tests/ui/const-generics/type_mismatch.stderr @@ -4,11 +4,11 @@ error: the constant `N` is not of type `u8` LL | bar::<N>() | ^ expected `u8`, found `usize` | -note: required by a bound in `bar` +note: required by a const generic parameter in `bar` --> $DIR/type_mismatch.rs:6:8 | LL | fn bar<const N: u8>() -> [u8; N] {} - | ^^^^^^^^^^^ required by this bound in `bar` + | ^^^^^^^^^^^ required by this const generic parameter in `bar` error[E0308]: mismatched types --> $DIR/type_mismatch.rs:6:26 diff --git a/tests/ui/const-generics/unify_with_nested_expr.stderr b/tests/ui/const-generics/unify_with_nested_expr.stderr index e050254a3e9..b1aecdb3cb5 100644 --- a/tests/ui/const-generics/unify_with_nested_expr.stderr +++ b/tests/ui/const-generics/unify_with_nested_expr.stderr @@ -4,14 +4,11 @@ error[E0284]: type annotations needed LL | bar(); | ^^^ cannot infer the value of the const parameter `N` declared on the function `bar` | -note: required by a bound in `bar` - --> $DIR/unify_with_nested_expr.rs:14:10 +note: required by a const generic parameter in `bar` + --> $DIR/unify_with_nested_expr.rs:12:8 | LL | fn bar<const N: usize>() - | --- required by a bound in this function -LL | where -LL | [(); N + 1]:, - | ^^^^^ required by this bound in `bar` + | ^^^^^^^^^^^^^^ required by this const generic parameter in `bar` help: consider specifying the generic argument | LL | bar::<N>(); diff --git a/tests/ui/consts/const-eval/unwind-abort.rs b/tests/ui/consts/const-eval/unwind-abort.rs index 57959e7db6a..26113e23888 100644 --- a/tests/ui/consts/const-eval/unwind-abort.rs +++ b/tests/ui/consts/const-eval/unwind-abort.rs @@ -1,4 +1,4 @@ -#![feature(c_unwind, const_extern_fn)] +#![feature(const_extern_fn)] const extern "C" fn foo() { panic!() //~ ERROR evaluation of constant value failed diff --git a/tests/ui/consts/unwind-abort.rs b/tests/ui/consts/unwind-abort.rs index 35db9152bd5..1dd33f327fb 100644 --- a/tests/ui/consts/unwind-abort.rs +++ b/tests/ui/consts/unwind-abort.rs @@ -1,6 +1,6 @@ //@ check-pass -#![feature(c_unwind, const_extern_fn)] +#![feature(const_extern_fn)] // We don't unwind in const-eval anyways. const extern "C" fn foo() { diff --git a/tests/ui/coroutine/break-inside-coroutine-issue-124495.rs b/tests/ui/coroutine/break-inside-coroutine-issue-124495.rs index 5d93db56722..97c3d06c023 100644 --- a/tests/ui/coroutine/break-inside-coroutine-issue-124495.rs +++ b/tests/ui/coroutine/break-inside-coroutine-issue-124495.rs @@ -18,6 +18,7 @@ async gen fn async_gen_fn() { fn main() { let _ = async { break; }; //~ ERROR `break` inside `async` block + let _ = async || { break; }; //~ ERROR `break` inside `async` closure let _ = gen { break; }; //~ ERROR `break` inside `gen` block diff --git a/tests/ui/coroutine/break-inside-coroutine-issue-124495.stderr b/tests/ui/coroutine/break-inside-coroutine-issue-124495.stderr index a7f37fad35e..f030961b7ed 100644 --- a/tests/ui/coroutine/break-inside-coroutine-issue-124495.stderr +++ b/tests/ui/coroutine/break-inside-coroutine-issue-124495.stderr @@ -38,16 +38,16 @@ LL | let _ = async { break; }; | enclosing `async` block error[E0267]: `break` inside `async` closure - --> $DIR/break-inside-coroutine-issue-124495.rs:21:24 + --> $DIR/break-inside-coroutine-issue-124495.rs:22:24 | LL | let _ = async || { break; }; - | --^^^^^--- - | | | - | | cannot `break` inside `async` closure - | enclosing `async` closure + | -----------^^^^^--- + | | | + | | cannot `break` inside `async` closure + | enclosing `async` closure error[E0267]: `break` inside `gen` block - --> $DIR/break-inside-coroutine-issue-124495.rs:23:19 + --> $DIR/break-inside-coroutine-issue-124495.rs:24:19 | LL | let _ = gen { break; }; | ------^^^^^--- @@ -56,7 +56,7 @@ LL | let _ = gen { break; }; | enclosing `gen` block error[E0267]: `break` inside `async gen` block - --> $DIR/break-inside-coroutine-issue-124495.rs:25:25 + --> $DIR/break-inside-coroutine-issue-124495.rs:26:25 | LL | let _ = async gen { break; }; | ------------^^^^^--- diff --git a/tests/ui/coverage-attr/bad-syntax.rs b/tests/ui/coverage-attr/bad-syntax.rs index 8783714992b..127179877e5 100644 --- a/tests/ui/coverage-attr/bad-syntax.rs +++ b/tests/ui/coverage-attr/bad-syntax.rs @@ -3,13 +3,13 @@ // Tests the error messages produced (or not produced) by various unusual // uses of the `#[coverage(..)]` attribute. -// FIXME(#84605): Multiple coverage attributes with the same value are useless, +// FIXME(#126658): Multiple coverage attributes with the same value are useless, // and should probably produce a diagnostic. #[coverage(off)] #[coverage(off)] fn multiple_consistent() {} -// FIXME(#84605): When there are multiple inconsistent coverage attributes, +// FIXME(#126658): When there are multiple inconsistent coverage attributes, // it's unclear which one will prevail. #[coverage(off)] #[coverage(on)] @@ -18,7 +18,7 @@ fn multiple_inconsistent() {} #[coverage] //~ ERROR expected `coverage(off)` or `coverage(on)` fn bare_word() {} -// FIXME(#84605): This shows as multiple different errors, one of which suggests +// FIXME(#126658): This shows as multiple different errors, one of which suggests // writing bare `#[coverage]`, which is not allowed. #[coverage = true] //~^ ERROR expected `coverage(off)` or `coverage(on)` @@ -48,7 +48,7 @@ fn bogus_word_after() {} #[coverage(off,)] fn comma_after() {} -// FIXME(#84605): This shows as multiple different errors. +// FIXME(#126658): This shows as multiple different errors. #[coverage(,off)] //~^ ERROR expected identifier, found `,` //~| HELP remove this comma diff --git a/tests/ui/coverage-attr/name-value.rs b/tests/ui/coverage-attr/name-value.rs new file mode 100644 index 00000000000..24c329780c5 --- /dev/null +++ b/tests/ui/coverage-attr/name-value.rs @@ -0,0 +1,64 @@ +#![feature(coverage_attribute)] +//@ edition: 2021 + +// Demonstrates the diagnostics produced when using the syntax +// `#[coverage = "off"]`, which should not be allowed. +// +// The syntax is tested both in places that can have a coverage attribute, +// and in places that cannot have a coverage attribute, to demonstrate the +// interaction between multiple errors. + +// FIXME(#126658): The error messages for using this syntax are inconsistent +// with the error message in other cases. They also sometimes appear together +// with other errors, and they suggest using the incorrect `#[coverage]` syntax. + +#[coverage = "off"] //~ ERROR malformed `coverage` attribute input +mod my_mod {} + +mod my_mod_inner { + #![coverage = "off"] //~ ERROR malformed `coverage` attribute input +} + +#[coverage = "off"] +//~^ ERROR `#[coverage]` must be applied to coverable code +//~| ERROR malformed `coverage` attribute input +struct MyStruct; + +#[coverage = "off"] //~ ERROR malformed `coverage` attribute input +impl MyStruct { + #[coverage = "off"] + //~^ ERROR `#[coverage]` must be applied to coverable code + //~| ERROR malformed `coverage` attribute input + const X: u32 = 7; +} + +#[coverage = "off"] //~ ERROR malformed `coverage` attribute input +trait MyTrait { + #[coverage = "off"] + //~^ ERROR `#[coverage]` must be applied to coverable code + //~| ERROR malformed `coverage` attribute input + const X: u32; + + #[coverage = "off"] + //~^ ERROR `#[coverage]` must be applied to coverable code + //~| ERROR malformed `coverage` attribute input + type T; +} + +#[coverage = "off"] //~ ERROR malformed `coverage` attribute input +impl MyTrait for MyStruct { + #[coverage = "off"] + //~^ ERROR `#[coverage]` must be applied to coverable code + //~| ERROR malformed `coverage` attribute input + const X: u32 = 8; + + #[coverage = "off"] + //~^ ERROR `#[coverage]` must be applied to coverable code + //~| ERROR malformed `coverage` attribute input + type T = (); +} + +#[coverage = "off"] +//~^ ERROR expected `coverage(off)` or `coverage(on)` +//~| ERROR malformed `coverage` attribute input +fn main() {} diff --git a/tests/ui/coverage-attr/name-value.stderr b/tests/ui/coverage-attr/name-value.stderr new file mode 100644 index 00000000000..90bc3a3b53b --- /dev/null +++ b/tests/ui/coverage-attr/name-value.stderr @@ -0,0 +1,219 @@ +error: malformed `coverage` attribute input + --> $DIR/name-value.rs:15:1 + | +LL | #[coverage = "off"] + | ^^^^^^^^^^^^^^^^^^^ + | +help: the following are the possible correct uses + | +LL | #[coverage(on|off)] + | ~~~~~~~~~~~~~~~~~~~ +LL | #[coverage] + | ~~~~~~~~~~~ + +error: malformed `coverage` attribute input + --> $DIR/name-value.rs:19:5 + | +LL | #![coverage = "off"] + | ^^^^^^^^^^^^^^^^^^^^ + | +help: the following are the possible correct uses + | +LL | #![coverage(on|off)] + | ~~~~~~~~~~~~~~~~~~~~ +LL | #![coverage] + | ~~~~~~~~~~~~ + +error: malformed `coverage` attribute input + --> $DIR/name-value.rs:22:1 + | +LL | #[coverage = "off"] + | ^^^^^^^^^^^^^^^^^^^ + | +help: the following are the possible correct uses + | +LL | #[coverage(on|off)] + | +LL | #[coverage] + | + +error: malformed `coverage` attribute input + --> $DIR/name-value.rs:29:5 + | +LL | #[coverage = "off"] + | ^^^^^^^^^^^^^^^^^^^ + | +help: the following are the possible correct uses + | +LL | #[coverage(on|off)] + | +LL | #[coverage] + | + +error: malformed `coverage` attribute input + --> $DIR/name-value.rs:27:1 + | +LL | #[coverage = "off"] + | ^^^^^^^^^^^^^^^^^^^ + | +help: the following are the possible correct uses + | +LL | #[coverage(on|off)] + | ~~~~~~~~~~~~~~~~~~~ +LL | #[coverage] + | ~~~~~~~~~~~ + +error: malformed `coverage` attribute input + --> $DIR/name-value.rs:37:5 + | +LL | #[coverage = "off"] + | ^^^^^^^^^^^^^^^^^^^ + | +help: the following are the possible correct uses + | +LL | #[coverage(on|off)] + | +LL | #[coverage] + | + +error: malformed `coverage` attribute input + --> $DIR/name-value.rs:42:5 + | +LL | #[coverage = "off"] + | ^^^^^^^^^^^^^^^^^^^ + | +help: the following are the possible correct uses + | +LL | #[coverage(on|off)] + | +LL | #[coverage] + | + +error: malformed `coverage` attribute input + --> $DIR/name-value.rs:35:1 + | +LL | #[coverage = "off"] + | ^^^^^^^^^^^^^^^^^^^ + | +help: the following are the possible correct uses + | +LL | #[coverage(on|off)] + | ~~~~~~~~~~~~~~~~~~~ +LL | #[coverage] + | ~~~~~~~~~~~ + +error: malformed `coverage` attribute input + --> $DIR/name-value.rs:50:5 + | +LL | #[coverage = "off"] + | ^^^^^^^^^^^^^^^^^^^ + | +help: the following are the possible correct uses + | +LL | #[coverage(on|off)] + | +LL | #[coverage] + | + +error: malformed `coverage` attribute input + --> $DIR/name-value.rs:55:5 + | +LL | #[coverage = "off"] + | ^^^^^^^^^^^^^^^^^^^ + | +help: the following are the possible correct uses + | +LL | #[coverage(on|off)] + | +LL | #[coverage] + | + +error: malformed `coverage` attribute input + --> $DIR/name-value.rs:48:1 + | +LL | #[coverage = "off"] + | ^^^^^^^^^^^^^^^^^^^ + | +help: the following are the possible correct uses + | +LL | #[coverage(on|off)] + | ~~~~~~~~~~~~~~~~~~~ +LL | #[coverage] + | ~~~~~~~~~~~ + +error: malformed `coverage` attribute input + --> $DIR/name-value.rs:61:1 + | +LL | #[coverage = "off"] + | ^^^^^^^^^^^^^^^^^^^ + | +help: the following are the possible correct uses + | +LL | #[coverage(on|off)] + | +LL | #[coverage] + | + +error[E0788]: `#[coverage]` must be applied to coverable code + --> $DIR/name-value.rs:22:1 + | +LL | #[coverage = "off"] + | ^^^^^^^^^^^^^^^^^^^ +... +LL | struct MyStruct; + | ---------------- not coverable code + +error[E0788]: `#[coverage]` must be applied to coverable code + --> $DIR/name-value.rs:37:5 + | +LL | #[coverage = "off"] + | ^^^^^^^^^^^^^^^^^^^ +... +LL | const X: u32; + | ------------- not coverable code + +error[E0788]: `#[coverage]` must be applied to coverable code + --> $DIR/name-value.rs:42:5 + | +LL | #[coverage = "off"] + | ^^^^^^^^^^^^^^^^^^^ +... +LL | type T; + | ------- not coverable code + +error[E0788]: `#[coverage]` must be applied to coverable code + --> $DIR/name-value.rs:29:5 + | +LL | #[coverage = "off"] + | ^^^^^^^^^^^^^^^^^^^ +... +LL | const X: u32 = 7; + | ----------------- not coverable code + +error[E0788]: `#[coverage]` must be applied to coverable code + --> $DIR/name-value.rs:50:5 + | +LL | #[coverage = "off"] + | ^^^^^^^^^^^^^^^^^^^ +... +LL | const X: u32 = 8; + | ----------------- not coverable code + +error[E0788]: `#[coverage]` must be applied to coverable code + --> $DIR/name-value.rs:55:5 + | +LL | #[coverage = "off"] + | ^^^^^^^^^^^^^^^^^^^ +... +LL | type T = (); + | ------------ not coverable code + +error: expected `coverage(off)` or `coverage(on)` + --> $DIR/name-value.rs:61:1 + | +LL | #[coverage = "off"] + | ^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 19 previous errors + +For more information about this error, try `rustc --explain E0788`. diff --git a/tests/ui/coverage-attr/subword.rs b/tests/ui/coverage-attr/subword.rs new file mode 100644 index 00000000000..98b8c25113c --- /dev/null +++ b/tests/ui/coverage-attr/subword.rs @@ -0,0 +1,19 @@ +#![feature(coverage_attribute)] +//@ edition: 2021 + +// Check that yes/no in `#[coverage(yes)]` and `#[coverage(no)]` must be bare +// words, not part of a more complicated substructure. + +#[coverage(yes(milord))] //~ ERROR expected `coverage(off)` or `coverage(on)` +fn yes_list() {} + +#[coverage(no(milord))] //~ ERROR expected `coverage(off)` or `coverage(on)` +fn no_list() {} + +#[coverage(yes = "milord")] //~ ERROR expected `coverage(off)` or `coverage(on)` +fn yes_key() {} + +#[coverage(no = "milord")] //~ ERROR expected `coverage(off)` or `coverage(on)` +fn no_key() {} + +fn main() {} diff --git a/tests/ui/coverage-attr/subword.stderr b/tests/ui/coverage-attr/subword.stderr new file mode 100644 index 00000000000..561573b8ada --- /dev/null +++ b/tests/ui/coverage-attr/subword.stderr @@ -0,0 +1,26 @@ +error: expected `coverage(off)` or `coverage(on)` + --> $DIR/subword.rs:7:1 + | +LL | #[coverage(yes(milord))] + | ^^^^^^^^^^^^^^^^^^^^^^^^ + +error: expected `coverage(off)` or `coverage(on)` + --> $DIR/subword.rs:10:1 + | +LL | #[coverage(no(milord))] + | ^^^^^^^^^^^^^^^^^^^^^^^ + +error: expected `coverage(off)` or `coverage(on)` + --> $DIR/subword.rs:13:1 + | +LL | #[coverage(yes = "milord")] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: expected `coverage(off)` or `coverage(on)` + --> $DIR/subword.rs:16:1 + | +LL | #[coverage(no = "milord")] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 4 previous errors + diff --git a/tests/ui/coverage-attr/word-only.rs b/tests/ui/coverage-attr/word-only.rs new file mode 100644 index 00000000000..5c723b1b6b6 --- /dev/null +++ b/tests/ui/coverage-attr/word-only.rs @@ -0,0 +1,54 @@ +#![feature(coverage_attribute)] +//@ edition: 2021 + +// Demonstrates the diagnostics produced when using the syntax `#[coverage]`, +// which should not be allowed. +// +// The syntax is tested both in places that can have a coverage attribute, +// and in places that cannot have a coverage attribute, to demonstrate the +// interaction between multiple errors. + +// FIXME(#126658): The error messages for using this syntax give the impression +// that it is legal, even though it should never be legal. + +// FIXME(#126658): This is silently allowed, but should not be. +#[coverage] +mod my_mod {} + +// FIXME(#126658): This is silently allowed, but should not be. +mod my_mod_inner { + #![coverage] +} + +#[coverage] //~ ERROR `#[coverage]` must be applied to coverable code +struct MyStruct; + +// FIXME(#126658): This is silently allowed, but should not be. +#[coverage] +impl MyStruct { + #[coverage] //~ ERROR `#[coverage]` must be applied to coverable code + const X: u32 = 7; +} + +// FIXME(#126658): This is silently allowed, but should not be. +#[coverage] +trait MyTrait { + #[coverage] //~ ERROR `#[coverage]` must be applied to coverable code + const X: u32; + + #[coverage] //~ ERROR `#[coverage]` must be applied to coverable code + type T; +} + +// FIXME(#126658): This is silently allowed, but should not be. +#[coverage] +impl MyTrait for MyStruct { + #[coverage] //~ ERROR `#[coverage]` must be applied to coverable code + const X: u32 = 8; + + #[coverage] //~ ERROR `#[coverage]` must be applied to coverable code + type T = (); +} + +#[coverage] //~ ERROR expected `coverage(off)` or `coverage(on)` +fn main() {} diff --git a/tests/ui/coverage-attr/word-only.stderr b/tests/ui/coverage-attr/word-only.stderr new file mode 100644 index 00000000000..bcafc23bc8d --- /dev/null +++ b/tests/ui/coverage-attr/word-only.stderr @@ -0,0 +1,57 @@ +error[E0788]: `#[coverage]` must be applied to coverable code + --> $DIR/word-only.rs:23:1 + | +LL | #[coverage] + | ^^^^^^^^^^^ +LL | struct MyStruct; + | ---------------- not coverable code + +error[E0788]: `#[coverage]` must be applied to coverable code + --> $DIR/word-only.rs:36:5 + | +LL | #[coverage] + | ^^^^^^^^^^^ +LL | const X: u32; + | ------------- not coverable code + +error[E0788]: `#[coverage]` must be applied to coverable code + --> $DIR/word-only.rs:39:5 + | +LL | #[coverage] + | ^^^^^^^^^^^ +LL | type T; + | ------- not coverable code + +error[E0788]: `#[coverage]` must be applied to coverable code + --> $DIR/word-only.rs:29:5 + | +LL | #[coverage] + | ^^^^^^^^^^^ +LL | const X: u32 = 7; + | ----------------- not coverable code + +error[E0788]: `#[coverage]` must be applied to coverable code + --> $DIR/word-only.rs:46:5 + | +LL | #[coverage] + | ^^^^^^^^^^^ +LL | const X: u32 = 8; + | ----------------- not coverable code + +error[E0788]: `#[coverage]` must be applied to coverable code + --> $DIR/word-only.rs:49:5 + | +LL | #[coverage] + | ^^^^^^^^^^^ +LL | type T = (); + | ------------ not coverable code + +error: expected `coverage(off)` or `coverage(on)` + --> $DIR/word-only.rs:53:1 + | +LL | #[coverage] + | ^^^^^^^^^^^ + +error: aborting due to 7 previous errors + +For more information about this error, try `rustc --explain E0788`. diff --git a/tests/ui/delegation/body-identity-glob.rs b/tests/ui/delegation/body-identity-glob.rs new file mode 100644 index 00000000000..58b644f46d6 --- /dev/null +++ b/tests/ui/delegation/body-identity-glob.rs @@ -0,0 +1,32 @@ +//@ check-pass + +#![feature(fn_delegation)] +#![allow(incomplete_features)] + +trait Trait { + fn foo(&self) {} + fn bar(&self) {} +} + +impl Trait for u8 {} + +struct S(u8); + +mod to_import { + pub fn check(arg: &u8) -> &u8 { arg } +} + +impl Trait for S { + reuse Trait::* { + use to_import::check; + + let _arr = Some(self.0).map(|x| [x * 2; 3]); + check(&self.0) + } +} + +fn main() { + let s = S(0); + s.foo(); + s.bar(); +} diff --git a/tests/ui/delegation/empty-glob.rs b/tests/ui/delegation/empty-glob.rs new file mode 100644 index 00000000000..d98579d8972 --- /dev/null +++ b/tests/ui/delegation/empty-glob.rs @@ -0,0 +1,11 @@ +#![feature(fn_delegation)] +#![allow(incomplete_features)] + +trait Trait {} + +struct S; +impl S { + reuse Trait::*; //~ ERROR empty glob delegation is not supported +} + +fn main() {} diff --git a/tests/ui/delegation/empty-glob.stderr b/tests/ui/delegation/empty-glob.stderr new file mode 100644 index 00000000000..f4d282f6a0f --- /dev/null +++ b/tests/ui/delegation/empty-glob.stderr @@ -0,0 +1,8 @@ +error: empty glob delegation is not supported + --> $DIR/empty-glob.rs:8:5 + | +LL | reuse Trait::*; + | ^^^^^^^^^^^^^^^ + +error: aborting due to 1 previous error + diff --git a/tests/ui/delegation/glob-bad-path.rs b/tests/ui/delegation/glob-bad-path.rs new file mode 100644 index 00000000000..7bc4f0153a3 --- /dev/null +++ b/tests/ui/delegation/glob-bad-path.rs @@ -0,0 +1,12 @@ +#![feature(fn_delegation)] +#![allow(incomplete_features)] + +trait Trait {} +struct S; + +impl Trait for u8 { + reuse unresolved::*; //~ ERROR failed to resolve: use of undeclared crate or module `unresolved` + reuse S::*; //~ ERROR expected trait, found struct `S` +} + +fn main() {} diff --git a/tests/ui/delegation/glob-bad-path.stderr b/tests/ui/delegation/glob-bad-path.stderr new file mode 100644 index 00000000000..0c06364b3f0 --- /dev/null +++ b/tests/ui/delegation/glob-bad-path.stderr @@ -0,0 +1,15 @@ +error: expected trait, found struct `S` + --> $DIR/glob-bad-path.rs:9:11 + | +LL | reuse S::*; + | ^ not a trait + +error[E0433]: failed to resolve: use of undeclared crate or module `unresolved` + --> $DIR/glob-bad-path.rs:8:11 + | +LL | reuse unresolved::*; + | ^^^^^^^^^^ use of undeclared crate or module `unresolved` + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0433`. diff --git a/tests/ui/delegation/glob-glob-conflict.rs b/tests/ui/delegation/glob-glob-conflict.rs new file mode 100644 index 00000000000..2843bf8c493 --- /dev/null +++ b/tests/ui/delegation/glob-glob-conflict.rs @@ -0,0 +1,33 @@ +#![feature(fn_delegation)] +#![allow(incomplete_features)] + +trait Trait1 { + fn method(&self) -> u8; +} +trait Trait2 { + fn method(&self) -> u8; +} +trait Trait { + fn method(&self) -> u8; +} + +impl Trait1 for u8 { + fn method(&self) -> u8 { 0 } +} +impl Trait1 for u16 { + fn method(&self) -> u8 { 1 } +} +impl Trait2 for u8 { + fn method(&self) -> u8 { 2 } +} + +impl Trait for u8 { + reuse Trait1::*; + reuse Trait2::*; //~ ERROR duplicate definitions with name `method` +} +impl Trait for u16 { + reuse Trait1::*; + reuse Trait1::*; //~ ERROR duplicate definitions with name `method` +} + +fn main() {} diff --git a/tests/ui/delegation/glob-glob-conflict.stderr b/tests/ui/delegation/glob-glob-conflict.stderr new file mode 100644 index 00000000000..8c7e5a4b023 --- /dev/null +++ b/tests/ui/delegation/glob-glob-conflict.stderr @@ -0,0 +1,25 @@ +error[E0201]: duplicate definitions with name `method`: + --> $DIR/glob-glob-conflict.rs:26:5 + | +LL | fn method(&self) -> u8; + | ----------------------- item in trait +... +LL | reuse Trait1::*; + | ---------------- previous definition here +LL | reuse Trait2::*; + | ^^^^^^^^^^^^^^^^ duplicate definition + +error[E0201]: duplicate definitions with name `method`: + --> $DIR/glob-glob-conflict.rs:30:5 + | +LL | fn method(&self) -> u8; + | ----------------------- item in trait +... +LL | reuse Trait1::*; + | ---------------- previous definition here +LL | reuse Trait1::*; + | ^^^^^^^^^^^^^^^^ duplicate definition + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0201`. diff --git a/tests/ui/delegation/glob-glob.rs b/tests/ui/delegation/glob-glob.rs new file mode 100644 index 00000000000..ef7f9a15e19 --- /dev/null +++ b/tests/ui/delegation/glob-glob.rs @@ -0,0 +1,36 @@ +//@ check-pass + +#![feature(fn_delegation)] +#![allow(incomplete_features)] + +mod inner { + pub trait TraitFoo { + fn foo(&self) -> u8; + } + pub trait TraitBar { + fn bar(&self) -> u8; + } + + impl TraitFoo for u8 { + fn foo(&self) -> u8 { 0 } + } + impl TraitBar for u8 { + fn bar(&self) -> u8 { 1 } + } +} + +trait Trait { + fn foo(&self) -> u8; + fn bar(&self) -> u8; +} + +impl Trait for u8 { + reuse inner::TraitFoo::*; + reuse inner::TraitBar::*; +} + +fn main() { + let u = 0u8; + u.foo(); + u.bar(); +} diff --git a/tests/ui/delegation/glob-non-fn.rs b/tests/ui/delegation/glob-non-fn.rs new file mode 100644 index 00000000000..ab312d51f49 --- /dev/null +++ b/tests/ui/delegation/glob-non-fn.rs @@ -0,0 +1,38 @@ +#![feature(fn_delegation)] +#![allow(incomplete_features)] + +trait Trait { + fn method(&self); + const CONST: u8; + type Type; + #[allow(non_camel_case_types)] + type method; +} + +impl Trait for u8 { + fn method(&self) {} + const CONST: u8 = 0; + type Type = u8; + type method = u8; +} + +struct Good(u8); +impl Trait for Good { + reuse Trait::* { &self.0 } + // Explicit definitions for non-delegatable items. + const CONST: u8 = 0; + type Type = u8; + type method = u8; +} + +struct Bad(u8); +impl Trait for Bad { //~ ERROR not all trait items implemented, missing: `CONST`, `Type`, `method` + reuse Trait::* { &self.0 } + //~^ ERROR item `CONST` is an associated method, which doesn't match its trait `Trait` + //~| ERROR item `Type` is an associated method, which doesn't match its trait `Trait` + //~| ERROR duplicate definitions with name `method` + //~| ERROR expected function, found associated constant `Trait::CONST` + //~| ERROR expected function, found associated type `Trait::Type` +} + +fn main() {} diff --git a/tests/ui/delegation/glob-non-fn.stderr b/tests/ui/delegation/glob-non-fn.stderr new file mode 100644 index 00000000000..4b918c53b84 --- /dev/null +++ b/tests/ui/delegation/glob-non-fn.stderr @@ -0,0 +1,62 @@ +error[E0324]: item `CONST` is an associated method, which doesn't match its trait `Trait` + --> $DIR/glob-non-fn.rs:30:5 + | +LL | const CONST: u8; + | ---------------- item in trait +... +LL | reuse Trait::* { &self.0 } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ does not match trait + +error[E0324]: item `Type` is an associated method, which doesn't match its trait `Trait` + --> $DIR/glob-non-fn.rs:30:5 + | +LL | type Type; + | ---------- item in trait +... +LL | reuse Trait::* { &self.0 } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ does not match trait + +error[E0201]: duplicate definitions with name `method`: + --> $DIR/glob-non-fn.rs:30:5 + | +LL | fn method(&self); + | ----------------- item in trait +... +LL | reuse Trait::* { &self.0 } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + | | + | duplicate definition + | previous definition here + +error[E0423]: expected function, found associated constant `Trait::CONST` + --> $DIR/glob-non-fn.rs:30:11 + | +LL | reuse Trait::* { &self.0 } + | ^^^^^ not a function + +error[E0423]: expected function, found associated type `Trait::Type` + --> $DIR/glob-non-fn.rs:30:11 + | +LL | reuse Trait::* { &self.0 } + | ^^^^^ + | + = note: can't use a type alias as a constructor + +error[E0046]: not all trait items implemented, missing: `CONST`, `Type`, `method` + --> $DIR/glob-non-fn.rs:29:1 + | +LL | const CONST: u8; + | --------------- `CONST` from trait +LL | type Type; + | --------- `Type` from trait +LL | #[allow(non_camel_case_types)] +LL | type method; + | ----------- `method` from trait +... +LL | impl Trait for Bad { + | ^^^^^^^^^^^^^^^^^^ missing `CONST`, `Type`, `method` in implementation + +error: aborting due to 6 previous errors + +Some errors have detailed explanations: E0046, E0201, E0324, E0423. +For more information about an error, try `rustc --explain E0046`. diff --git a/tests/ui/delegation/glob-non-impl.rs b/tests/ui/delegation/glob-non-impl.rs new file mode 100644 index 00000000000..d523731eeb3 --- /dev/null +++ b/tests/ui/delegation/glob-non-impl.rs @@ -0,0 +1,20 @@ +#![feature(fn_delegation)] +#![allow(incomplete_features)] + +trait Trait { + fn method() {} +} + +reuse Trait::*; //~ ERROR glob delegation is only supported in impls + +trait OtherTrait { + reuse Trait::*; //~ ERROR glob delegation is only supported in impls +} + +extern { + reuse Trait::*; //~ ERROR delegation is not supported in `extern` blocks +} + +fn main() { + reuse Trait::*; //~ ERROR glob delegation is only supported in impls +} diff --git a/tests/ui/delegation/glob-non-impl.stderr b/tests/ui/delegation/glob-non-impl.stderr new file mode 100644 index 00000000000..ea458fd5e90 --- /dev/null +++ b/tests/ui/delegation/glob-non-impl.stderr @@ -0,0 +1,26 @@ +error: delegation is not supported in `extern` blocks + --> $DIR/glob-non-impl.rs:15:5 + | +LL | reuse Trait::*; + | ^^^^^^^^^^^^^^^ + +error: glob delegation is only supported in impls + --> $DIR/glob-non-impl.rs:8:1 + | +LL | reuse Trait::*; + | ^^^^^^^^^^^^^^^ + +error: glob delegation is only supported in impls + --> $DIR/glob-non-impl.rs:11:5 + | +LL | reuse Trait::*; + | ^^^^^^^^^^^^^^^ + +error: glob delegation is only supported in impls + --> $DIR/glob-non-impl.rs:19:5 + | +LL | reuse Trait::*; + | ^^^^^^^^^^^^^^^ + +error: aborting due to 4 previous errors + diff --git a/tests/ui/delegation/glob-override.rs b/tests/ui/delegation/glob-override.rs new file mode 100644 index 00000000000..1d0dcf1df6e --- /dev/null +++ b/tests/ui/delegation/glob-override.rs @@ -0,0 +1,37 @@ +//@ check-pass + +#![feature(fn_delegation)] +#![allow(incomplete_features)] + +trait Trait { + fn foo(&self) -> u8; + fn bar(&self) -> u8; +} + +impl Trait for u8 { + fn foo(&self) -> u8 { 0 } + fn bar(&self) -> u8 { 1 } +} + +struct S(u8); +struct Z(u8); + +impl Trait for S { + reuse Trait::* { &self.0 } + fn bar(&self) -> u8 { 2 } +} + +impl Trait for Z { + reuse Trait::* { &self.0 } + reuse Trait::bar { &self.0 } +} + +fn main() { + let s = S(2); + s.foo(); + s.bar(); + + let z = Z(2); + z.foo(); + z.bar(); +} diff --git a/tests/ui/delegation/glob.rs b/tests/ui/delegation/glob.rs new file mode 100644 index 00000000000..5bc80c16648 --- /dev/null +++ b/tests/ui/delegation/glob.rs @@ -0,0 +1,35 @@ +//@ check-pass + +#![feature(fn_delegation)] +#![allow(incomplete_features)] + +trait Trait { + fn foo(&self) -> u8; + fn bar(&self) -> u8; +} + +impl Trait for u8 { + fn foo(&self) -> u8 { 0 } + fn bar(&self) -> u8 { 1 } +} + +struct S(u8); +struct Z(u8); + +impl Trait for S { + reuse Trait::* { &self.0 } +} + +impl Trait for Z { + reuse <u8 as Trait>::* { &self.0 } +} + +fn main() { + let s = S(2); + s.foo(); + s.bar(); + + let z = Z(3); + z.foo(); + z.bar(); +} diff --git a/tests/ui/delegation/macro-inside-glob.rs b/tests/ui/delegation/macro-inside-glob.rs new file mode 100644 index 00000000000..1d529341c5b --- /dev/null +++ b/tests/ui/delegation/macro-inside-glob.rs @@ -0,0 +1,26 @@ +//@ check-pass + +#![feature(fn_delegation)] +#![allow(incomplete_features)] + +trait Trait { + fn foo(&self) -> u8 { 0 } + fn bar(&self) -> u8 { 1 } +} + +impl Trait for u8 {} + +struct S(u8); + +// Macro expansion works inside delegation items. +macro_rules! u8 { () => { u8 } } +macro_rules! self_0 { ($self:ident) => { &$self.0 } } +impl Trait for S { + reuse <u8!() as Trait>::* { self_0!(self) } +} + +fn main() { + let s = S(2); + s.foo(); + s.bar(); +} diff --git a/tests/ui/drop/auxiliary/edition-2021-macros.rs b/tests/ui/drop/auxiliary/edition-2021-macros.rs new file mode 100644 index 00000000000..8a6444f8614 --- /dev/null +++ b/tests/ui/drop/auxiliary/edition-2021-macros.rs @@ -0,0 +1,8 @@ +//@ edition:2021 + +#[macro_export] +macro_rules! edition_2021_block { + ($($c:tt)*) => { + { $($c)* } + } +} diff --git a/tests/ui/drop/auxiliary/edition-2024-macros.rs b/tests/ui/drop/auxiliary/edition-2024-macros.rs new file mode 100644 index 00000000000..236340bfed4 --- /dev/null +++ b/tests/ui/drop/auxiliary/edition-2024-macros.rs @@ -0,0 +1,9 @@ +//@ edition:2024 +//@ compile-flags: -Zunstable-options + +#[macro_export] +macro_rules! edition_2024_block { + ($($c:tt)*) => { + { $($c)* } + } +} diff --git a/tests/ui/drop/tail-expr-drop-order-negative.edition2024.stderr b/tests/ui/drop/tail-expr-drop-order-negative.edition2024.stderr new file mode 100644 index 00000000000..75fc34e409b --- /dev/null +++ b/tests/ui/drop/tail-expr-drop-order-negative.edition2024.stderr @@ -0,0 +1,16 @@ +error[E0716]: temporary value dropped while borrowed + --> $DIR/tail-expr-drop-order-negative.rs:11:15 + | +LL | x.replace(std::cell::RefCell::new(123).borrow()).is_some() + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - temporary value is freed at the end of this statement + | | + | creates a temporary value which is freed while still in use +LL | +LL | } + | - borrow might be used here, when `x` is dropped and runs the destructor for type `Option<Ref<'_, i32>>` + | + = note: consider using a `let` binding to create a longer lived value + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0716`. diff --git a/tests/ui/drop/tail-expr-drop-order-negative.rs b/tests/ui/drop/tail-expr-drop-order-negative.rs new file mode 100644 index 00000000000..c570b3a1ee2 --- /dev/null +++ b/tests/ui/drop/tail-expr-drop-order-negative.rs @@ -0,0 +1,17 @@ +//@ revisions: edition2021 edition2024 +//@ [edition2024] compile-flags: -Zunstable-options +//@ [edition2024] edition: 2024 +//@ [edition2021] check-pass + +#![feature(shorter_tail_lifetimes)] + +fn why_would_you_do_this() -> bool { + let mut x = None; + // Make a temporary `RefCell` and put a `Ref` that borrows it in `x`. + x.replace(std::cell::RefCell::new(123).borrow()).is_some() + //[edition2024]~^ ERROR: temporary value dropped while borrowed +} + +fn main() { + why_would_you_do_this(); +} diff --git a/tests/ui/drop/tail-expr-drop-order.rs b/tests/ui/drop/tail-expr-drop-order.rs new file mode 100644 index 00000000000..5d87f980b15 --- /dev/null +++ b/tests/ui/drop/tail-expr-drop-order.rs @@ -0,0 +1,108 @@ +//@ aux-build:edition-2021-macros.rs +//@ aux-build:edition-2024-macros.rs +//@ compile-flags: -Z validate-mir -Zunstable-options +//@ edition: 2024 +//@ run-pass + +#![feature(shorter_tail_lifetimes)] +#![allow(unused_imports)] +#![allow(dead_code)] +#![allow(unused_variables)] + +#[macro_use] +extern crate edition_2021_macros; +#[macro_use] +extern crate edition_2024_macros; +use std::cell::RefCell; +use std::convert::TryInto; + +#[derive(Default)] +struct DropOrderCollector(RefCell<Vec<u32>>); + +struct LoudDrop<'a>(&'a DropOrderCollector, u32); + +impl Drop for LoudDrop<'_> { + fn drop(&mut self) { + println!("{}", self.1); + self.0.0.borrow_mut().push(self.1); + } +} + +impl DropOrderCollector { + fn option_loud_drop(&self, n: u32) -> Option<LoudDrop> { + Some(LoudDrop(self, n)) + } + + fn loud_drop(&self, n: u32) -> LoudDrop { + LoudDrop(self, n) + } + + fn assert_sorted(&self, expected: usize) { + let result = self.0.borrow(); + assert_eq!(result.len(), expected); + for i in 1..result.len() { + assert!( + result[i - 1] < result[i], + "inversion at {} ({} followed by {})", + i - 1, + result[i - 1], + result[i] + ); + } + } +} + +fn edition_2021_around_2021() { + let c = DropOrderCollector::default(); + let _ = edition_2021_block! { + let a = c.loud_drop(1); + edition_2021_block! { + let b = c.loud_drop(0); + c.loud_drop(2).1 + } + }; + c.assert_sorted(3); +} + +fn edition_2021_around_2024() { + let c = DropOrderCollector::default(); + let _ = edition_2021_block! { + let a = c.loud_drop(2); + edition_2024_block! { + let b = c.loud_drop(1); + c.loud_drop(0).1 + } + }; + c.assert_sorted(3); +} + +fn edition_2024_around_2021() { + let c = DropOrderCollector::default(); + let _ = edition_2024_block! { + let a = c.loud_drop(2); + edition_2021_block! { + let b = c.loud_drop(0); + c.loud_drop(1).1 + } + }; + c.assert_sorted(3); +} + +fn edition_2024_around_2024() { + let c = DropOrderCollector::default(); + let _ = edition_2024_block! { + let a = c.loud_drop(2); + edition_2024_block! { + let b = c.loud_drop(1); + c.loud_drop(0).1 + } + }; + c.assert_sorted(3); +} + +fn main() { + edition_2021_around_2021(); + edition_2021_around_2024(); + edition_2024_around_2021(); + edition_2024_around_2024(); +} diff --git a/tests/ui/feature-gates/feature-gate-shorter_tail_lifetimes.rs b/tests/ui/feature-gates/feature-gate-shorter_tail_lifetimes.rs new file mode 100644 index 00000000000..5292c44bb2d --- /dev/null +++ b/tests/ui/feature-gates/feature-gate-shorter_tail_lifetimes.rs @@ -0,0 +1,8 @@ +fn f() -> usize { + let c = std::cell::RefCell::new(".."); + c.borrow().len() //~ ERROR: `c` does not live long enough +} + +fn main() { + let _ = f(); +} diff --git a/tests/ui/feature-gates/feature-gate-shorter_tail_lifetimes.stderr b/tests/ui/feature-gates/feature-gate-shorter_tail_lifetimes.stderr new file mode 100644 index 00000000000..648c3d5daa1 --- /dev/null +++ b/tests/ui/feature-gates/feature-gate-shorter_tail_lifetimes.stderr @@ -0,0 +1,26 @@ +error[E0597]: `c` does not live long enough + --> $DIR/feature-gate-shorter_tail_lifetimes.rs:3:5 + | +LL | let c = std::cell::RefCell::new(".."); + | - binding `c` declared here +LL | c.borrow().len() + | ^--------- + | | + | borrowed value does not live long enough + | a temporary with access to the borrow is created here ... +LL | } + | - + | | + | `c` dropped here while still borrowed + | ... and the borrow might be used here, when that temporary is dropped and runs the destructor for type `Ref<'_, &str>` + | + = note: the temporary is part of an expression at the end of a block; + consider forcing this temporary to be dropped sooner, before the block's local variables are dropped +help: for example, you could save the expression's value in a new local variable `x` and then make `x` be the expression at the end of the block + | +LL | let x = c.borrow().len(); x + | +++++++ +++ + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0597`. diff --git a/tests/ui/feature-gates/feature-gate-unsafe-extern-blocks.rs b/tests/ui/feature-gates/feature-gate-unsafe-extern-blocks.rs index eab134a4a4d..3ea62e875b8 100644 --- a/tests/ui/feature-gates/feature-gate-unsafe-extern-blocks.rs +++ b/tests/ui/feature-gates/feature-gate-unsafe-extern-blocks.rs @@ -2,4 +2,12 @@ unsafe extern "C" { //~^ ERROR extern block cannot be declared unsafe } +// We can't gate `unsafe extern` blocks themselves since they were previously +// allowed, but we should gate the `safe` soft keyword. +#[cfg(any())] +unsafe extern "C" { + safe fn foo(); + //~^ ERROR `unsafe extern {}` blocks and `safe` keyword are experimental +} + fn main() {} diff --git a/tests/ui/feature-gates/feature-gate-unsafe-extern-blocks.stderr b/tests/ui/feature-gates/feature-gate-unsafe-extern-blocks.stderr index 7e9b199a2db..84f00827c60 100644 --- a/tests/ui/feature-gates/feature-gate-unsafe-extern-blocks.stderr +++ b/tests/ui/feature-gates/feature-gate-unsafe-extern-blocks.stderr @@ -4,5 +4,16 @@ error: extern block cannot be declared unsafe LL | unsafe extern "C" { | ^^^^^^ -error: aborting due to 1 previous error +error[E0658]: `unsafe extern {}` blocks and `safe` keyword are experimental + --> $DIR/feature-gate-unsafe-extern-blocks.rs:9:5 + | +LL | safe fn foo(); + | ^^^^ + | + = note: see issue #123743 <https://github.com/rust-lang/rust/issues/123743> for more information + = help: add `#![feature(unsafe_extern_blocks)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error: aborting due to 2 previous errors +For more information about this error, try `rustc --explain E0658`. diff --git a/tests/ui/higher-ranked/structually-relate-aliases.stderr b/tests/ui/higher-ranked/structually-relate-aliases.stderr index e1cffa0fc37..2f1dfd19c48 100644 --- a/tests/ui/higher-ranked/structually-relate-aliases.stderr +++ b/tests/ui/higher-ranked/structually-relate-aliases.stderr @@ -1,5 +1,5 @@ - WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: AliasTy { args: [?1t, '^0.Named(DefId(0:15 ~ structually_relate_aliases[de75]::{impl#1}::'a), "'a")], def_id: DefId(0:5 ~ structually_relate_aliases[de75]::ToUnit::Unit), _use_alias_ty_new_instead: () } - WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: AliasTy { args: [?1t, !2_0.Named(DefId(0:15 ~ structually_relate_aliases[de75]::{impl#1}::'a), "'a")], def_id: DefId(0:5 ~ structually_relate_aliases[de75]::ToUnit::Unit), _use_alias_ty_new_instead: () } + WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: AliasTy { args: [?1t, '^0.Named(DefId(0:15 ~ structually_relate_aliases[de75]::{impl#1}::'a), "'a")], def_id: DefId(0:5 ~ structually_relate_aliases[de75]::ToUnit::Unit) } + WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: AliasTy { args: [?1t, !2_0.Named(DefId(0:15 ~ structually_relate_aliases[de75]::{impl#1}::'a), "'a")], def_id: DefId(0:5 ~ structually_relate_aliases[de75]::ToUnit::Unit) } error[E0277]: the trait bound `for<'a> T: ToUnit<'a>` is not satisfied --> $DIR/structually-relate-aliases.rs:13:36 | diff --git a/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/norm-before-method-resolution-opaque-type.next.stderr b/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/norm-before-method-resolution-opaque-type.next.stderr new file mode 100644 index 00000000000..72646b7bc76 --- /dev/null +++ b/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/norm-before-method-resolution-opaque-type.next.stderr @@ -0,0 +1,9 @@ +error[E0284]: type annotations needed: cannot satisfy `Foo == _` + --> $DIR/norm-before-method-resolution-opaque-type.rs:16:19 + | +LL | fn weird_bound<X>(x: &<X as Trait<'static>>::Out<Foo>) -> X + | ^ cannot satisfy `Foo == _` + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0284`. diff --git a/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/norm-before-method-resolution-opaque-type.old.stderr b/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/norm-before-method-resolution-opaque-type.old.stderr new file mode 100644 index 00000000000..dbd0d5dc733 --- /dev/null +++ b/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/norm-before-method-resolution-opaque-type.old.stderr @@ -0,0 +1,36 @@ +error: item does not constrain `Foo::{opaque#0}`, but has it in its signature + --> $DIR/norm-before-method-resolution-opaque-type.rs:16:4 + | +LL | fn weird_bound<X>(x: &<X as Trait<'static>>::Out<Foo>) -> X + | ^^^^^^^^^^^ + | + = note: consider moving the opaque type's declaration and defining uses into a separate module +note: this opaque type is in the signature + --> $DIR/norm-before-method-resolution-opaque-type.rs:13:12 + | +LL | type Foo = impl Sized; + | ^^^^^^^^^^ + +error: unconstrained opaque type + --> $DIR/norm-before-method-resolution-opaque-type.rs:13:12 + | +LL | type Foo = impl Sized; + | ^^^^^^^^^^ + | + = note: `Foo` must be used in combination with a concrete type within the same module + +error[E0507]: cannot move out of `*x` which is behind a shared reference + --> $DIR/norm-before-method-resolution-opaque-type.rs:23:13 + | +LL | let x = *x; + | ^^ move occurs because `*x` has type `<X as Trait<'_>>::Out<Foo>`, which does not implement the `Copy` trait + | +help: consider removing the dereference here + | +LL - let x = *x; +LL + let x = x; + | + +error: aborting due to 3 previous errors + +For more information about this error, try `rustc --explain E0507`. diff --git a/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/norm-before-method-resolution-opaque-type.rs b/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/norm-before-method-resolution-opaque-type.rs new file mode 100644 index 00000000000..cf752f814c9 --- /dev/null +++ b/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/norm-before-method-resolution-opaque-type.rs @@ -0,0 +1,29 @@ +//@ revisions: old next +//@[next] compile-flags: -Znext-solver + +#![feature(type_alias_impl_trait)] +trait Trait<'a> { + type Out<U>; +} + +impl<'a, T> Trait<'a> for T { + type Out<U> = T; +} + +type Foo = impl Sized; +//[old]~^ ERROR: unconstrained opaque type + +fn weird_bound<X>(x: &<X as Trait<'static>>::Out<Foo>) -> X +//[old]~^ ERROR: item does not constrain +//[next]~^^ ERROR: cannot satisfy `Foo == _` +where + for<'a> X: Trait<'a>, + for<'a> <X as Trait<'a>>::Out<()>: Copy, +{ + let x = *x; //[old]~ ERROR: cannot move out of `*x` + todo!(); +} + +fn main() { + let _: () = weird_bound(&()); +} diff --git a/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/norm-before-method-resolution.rs b/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/norm-before-method-resolution.rs index e1aa1babdbb..f0e13a74b2c 100644 --- a/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/norm-before-method-resolution.rs +++ b/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/norm-before-method-resolution.rs @@ -1,6 +1,6 @@ //@ check-pass -// Should pass, but we normalize and check bounds before we resolve the generics +// We normalize and check bounds before we resolve the generics // of the function (which we know because of the return type). trait Trait<'a> { @@ -12,10 +12,12 @@ impl<'a, T> Trait<'a> for T { } fn weird_bound<X>() -> X - where - for<'a> X: Trait<'a>, - for<'a> <X as Trait<'a>>::Out: Copy -{ todo!() } +where + for<'a> X: Trait<'a>, + for<'a> <X as Trait<'a>>::Out: Copy, +{ + todo!() +} fn main() { let _: () = weird_bound(); diff --git a/tests/ui/impl-trait/lazy_subtyping_of_opaques.rs b/tests/ui/impl-trait/lazy_subtyping_of_opaques.rs index 65331894725..8fd1f35645a 100644 --- a/tests/ui/impl-trait/lazy_subtyping_of_opaques.rs +++ b/tests/ui/impl-trait/lazy_subtyping_of_opaques.rs @@ -2,58 +2,23 @@ //! No hidden types are being constrained in the subtyping predicate, but type and //! lifetime variables get subtyped in the generic parameter list of the opaque. -use std::iter; - -mod either { - pub enum Either<L, R> { - Left(L), - Right(R), - } - - impl<L: Iterator, R: Iterator<Item = L::Item>> Iterator for Either<L, R> { - type Item = L::Item; - fn next(&mut self) -> Option<Self::Item> { - todo!() - } - } - pub use self::Either::{Left, Right}; -} - -pub enum BabeConsensusLogRef<'a> { - NextEpochData(BabeNextEpochRef<'a>), - NextConfigData, -} - -impl<'a> BabeConsensusLogRef<'a> { - pub fn scale_encoding( - &self, - ) -> impl Iterator<Item = impl AsRef<[u8]> + Clone + 'a> + Clone + 'a { - //~^ ERROR is not satisfied - //~| ERROR is not satisfied - //~| ERROR is not satisfied - match self { - BabeConsensusLogRef::NextEpochData(digest) => either::Left(either::Left( - digest.scale_encoding().map(either::Left).map(either::Left), - )), - BabeConsensusLogRef::NextConfigData => either::Right( - // The Opaque type from ``scale_encoding` gets used opaquely here, while the `R` - // generic parameter of `Either` contains type variables that get subtyped and the - // opaque type contains lifetime variables that get subtyped. - iter::once(either::Right(either::Left([1]))) - .chain(std::iter::once([1]).map(either::Right).map(either::Right)), - ), - } - } -} - -pub struct BabeNextEpochRef<'a>(&'a ()); - -impl<'a> BabeNextEpochRef<'a> { - pub fn scale_encoding( - &self, - ) -> impl Iterator<Item = impl AsRef<[u8]> + Clone + 'a> + Clone + 'a { - std::iter::once([1]) +//@ check-pass + +fn foo() -> impl Default + Copy { + if false { + let x = Default::default(); + // add `Subtype(?x, ?y)` obligation + let y = x; + + // Make a tuple `(?x, ?y)` and equate it with `(impl Default, u32)`. + // For us to try and prove a `Subtype(impl Default, u32)` obligation, + // we have to instantiate both `?x` and `?y` without any + // `select_where_possible` calls inbetween. + let mut tup = &mut (x, y); + let assign_tup = &mut (foo(), 1u32); + tup = assign_tup; } + 1u32 } fn main() {} diff --git a/tests/ui/impl-trait/lazy_subtyping_of_opaques.stderr b/tests/ui/impl-trait/lazy_subtyping_of_opaques.stderr deleted file mode 100644 index 2f8c957c2c7..00000000000 --- a/tests/ui/impl-trait/lazy_subtyping_of_opaques.stderr +++ /dev/null @@ -1,21 +0,0 @@ -error[E0277]: the trait bound `Either<Either<Map<Map<impl Iterator<Item = impl AsRef<[u8]> + Clone + '_> + Clone + '_, fn(impl AsRef<[u8]> + Clone + '_) -> Either<impl AsRef<[u8]> + Clone + '_, _> {Either::<impl AsRef<[u8]> + Clone + '_, _>::Left}>, fn(Either<impl AsRef<[u8]> + Clone + '_, _>) -> Either<Either<impl AsRef<[u8]> + Clone + '_, _>, Either<[{integer}; 1], [{integer}; 1]>> {Either::<Either<impl AsRef<[u8]> + Clone + '_, _>, Either<[{integer}; 1], [{integer}; 1]>>::Left}>, _>, std::iter::Chain<std::iter::Once<Either<Either<impl AsRef<[u8]> + Clone + '_, _>, Either<[{integer}; 1], [{integer}; 1]>>>, Map<Map<std::iter::Once<[{integer}; 1]>, fn([{integer}; 1]) -> Either<[{integer}; 1], [{integer}; 1]> {Either::<[{integer}; 1], [{integer}; 1]>::Right}>, fn(Either<[{integer}; 1], [{integer}; 1]>) -> Either<Either<impl AsRef<[u8]> + Clone + '_, _>, Either<[{integer}; 1], [{integer}; 1]>> {Either::<Either<impl AsRef<[u8]> + Clone + '_, _>, Either<[{integer}; 1], [{integer}; 1]>>::Right}>>>: Clone` is not satisfied - --> $DIR/lazy_subtyping_of_opaques.rs:30:10 - | -LL | ) -> impl Iterator<Item = impl AsRef<[u8]> + Clone + 'a> + Clone + 'a { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Clone` is not implemented for `Either<Either<Map<Map<impl Iterator<Item = impl AsRef<[u8]> + Clone + '_> + Clone + '_, fn(impl AsRef<[u8]> + Clone + '_) -> Either<impl AsRef<[u8]> + Clone + '_, _> {Either::<impl AsRef<[u8]> + Clone + '_, _>::Left}>, fn(Either<impl AsRef<[u8]> + Clone + '_, _>) -> Either<Either<impl AsRef<[u8]> + Clone + '_, _>, Either<[{integer}; 1], [{integer}; 1]>> {Either::<Either<impl AsRef<[u8]> + Clone + '_, _>, Either<[{integer}; 1], [{integer}; 1]>>::Left}>, _>, std::iter::Chain<std::iter::Once<Either<Either<impl AsRef<[u8]> + Clone + '_, _>, Either<[{integer}; 1], [{integer}; 1]>>>, Map<Map<std::iter::Once<[{integer}; 1]>, fn([{integer}; 1]) -> Either<[{integer}; 1], [{integer}; 1]> {Either::<[{integer}; 1], [{integer}; 1]>::Right}>, fn(Either<[{integer}; 1], [{integer}; 1]>) -> Either<Either<impl AsRef<[u8]> + Clone + '_, _>, Either<[{integer}; 1], [{integer}; 1]>> {Either::<Either<impl AsRef<[u8]> + Clone + '_, _>, Either<[{integer}; 1], [{integer}; 1]>>::Right}>>>` - -error[E0277]: the trait bound `Either<Either<impl AsRef<[u8]> + Clone + '_, _>, Either<[{integer}; 1], [{integer}; 1]>>: AsRef<[u8]>` is not satisfied - --> $DIR/lazy_subtyping_of_opaques.rs:30:31 - | -LL | ) -> impl Iterator<Item = impl AsRef<[u8]> + Clone + 'a> + Clone + 'a { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `AsRef<[u8]>` is not implemented for `Either<Either<impl AsRef<[u8]> + Clone + '_, _>, Either<[{integer}; 1], [{integer}; 1]>>` - -error[E0277]: the trait bound `Either<Either<impl AsRef<[u8]> + Clone + '_, _>, Either<[{integer}; 1], [{integer}; 1]>>: Clone` is not satisfied - --> $DIR/lazy_subtyping_of_opaques.rs:30:31 - | -LL | ) -> impl Iterator<Item = impl AsRef<[u8]> + Clone + 'a> + Clone + 'a { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Clone` is not implemented for `Either<Either<impl AsRef<[u8]> + Clone + '_, _>, Either<[{integer}; 1], [{integer}; 1]>>` - -error: aborting due to 3 previous errors - -For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/impl-trait/upvar_captures.rs b/tests/ui/impl-trait/upvar_captures.rs new file mode 100644 index 00000000000..61e3cda66f5 --- /dev/null +++ b/tests/ui/impl-trait/upvar_captures.rs @@ -0,0 +1,16 @@ +//! This test used to ICE: rust-lang/rust#123255 +//! Because the errors on `C` were ignored when trying +//! to compute the MIR of the closure, which thus ended +//! up with broken upvars. +//@ edition:2021 +#![crate_type = "lib"] + +pub fn a() {} + +mod handlers { + pub struct C(&()); //~ ERROR missing lifetime specifier + pub fn c() -> impl Fn() -> C { + let a1 = (); + || C((crate::a(), a1).into()) + } +} diff --git a/tests/ui/impl-trait/upvar_captures.stderr b/tests/ui/impl-trait/upvar_captures.stderr new file mode 100644 index 00000000000..b87a16606cc --- /dev/null +++ b/tests/ui/impl-trait/upvar_captures.stderr @@ -0,0 +1,14 @@ +error[E0106]: missing lifetime specifier + --> $DIR/upvar_captures.rs:11:18 + | +LL | pub struct C(&()); + | ^ expected named lifetime parameter + | +help: consider introducing a named lifetime parameter + | +LL | pub struct C<'a>(&'a ()); + | ++++ ++ + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0106`. diff --git a/tests/ui/inference/issue-83606.stderr b/tests/ui/inference/issue-83606.stderr index 8e6ff6d568d..69d1d71ef3c 100644 --- a/tests/ui/inference/issue-83606.stderr +++ b/tests/ui/inference/issue-83606.stderr @@ -1,9 +1,14 @@ -error[E0282]: type annotations needed for `[usize; _]` +error[E0284]: type annotations needed for `[usize; _]` --> $DIR/issue-83606.rs:8:9 | LL | let _ = foo("foo"); - | ^ + | ^ ---------- type must be known at this point | +note: required by a const generic parameter in `foo` + --> $DIR/issue-83606.rs:3:8 + | +LL | fn foo<const N: usize>(_: impl std::fmt::Display) -> [usize; N] { + | ^^^^^^^^^^^^^^ required by this const generic parameter in `foo` help: consider giving this pattern a type, where the value of const parameter `N` is specified | LL | let _: [usize; N] = foo("foo"); @@ -11,4 +16,4 @@ LL | let _: [usize; N] = foo("foo"); error: aborting due to 1 previous error -For more information about this error, try `rustc --explain E0282`. +For more information about this error, try `rustc --explain E0284`. diff --git a/tests/ui/issues/issue-98299.rs b/tests/ui/issues/issue-98299.rs index 63c058f91fc..ba63d963475 100644 --- a/tests/ui/issues/issue-98299.rs +++ b/tests/ui/issues/issue-98299.rs @@ -3,6 +3,8 @@ use std::convert::TryFrom; pub fn test_usage(p: ()) { SmallCString::try_from(p).map(|cstr| cstr); //~^ ERROR: type annotations needed + //~| ERROR: type annotations needed + //~| ERROR: type annotations needed } pub struct SmallCString<const N: usize> {} diff --git a/tests/ui/issues/issue-98299.stderr b/tests/ui/issues/issue-98299.stderr index becf16d1db9..b645267e3b9 100644 --- a/tests/ui/issues/issue-98299.stderr +++ b/tests/ui/issues/issue-98299.stderr @@ -1,14 +1,61 @@ -error[E0282]: type annotations needed for `SmallCString<_>` +error[E0284]: type annotations needed for `SmallCString<_>` --> $DIR/issue-98299.rs:4:36 | LL | SmallCString::try_from(p).map(|cstr| cstr); - | ^^^^ + | ------------ ^^^^ + | | + | type must be known at this point | +note: required by a const generic parameter in `SmallCString` + --> $DIR/issue-98299.rs:10:25 + | +LL | pub struct SmallCString<const N: usize> {} + | ^^^^^^^^^^^^^^ required by this const generic parameter in `SmallCString` +help: consider giving this closure parameter an explicit type, where the value of const parameter `N` is specified + | +LL | SmallCString::try_from(p).map(|cstr: SmallCString<N>| cstr); + | +++++++++++++++++ + +error[E0284]: type annotations needed for `SmallCString<_>` + --> $DIR/issue-98299.rs:4:36 + | +LL | SmallCString::try_from(p).map(|cstr| cstr); + | ------------ ^^^^ + | | + | type must be known at this point + | +note: required for `SmallCString<_>` to implement `TryFrom<()>` + --> $DIR/issue-98299.rs:12:22 + | +LL | impl<const N: usize> TryFrom<()> for SmallCString<N> { + | -------------- ^^^^^^^^^^^ ^^^^^^^^^^^^^^^ + | | + | unsatisfied trait bound introduced here +help: consider giving this closure parameter an explicit type, where the value of const parameter `N` is specified + | +LL | SmallCString::try_from(p).map(|cstr: SmallCString<N>| cstr); + | +++++++++++++++++ + +error[E0284]: type annotations needed for `SmallCString<_>` + --> $DIR/issue-98299.rs:4:36 + | +LL | SmallCString::try_from(p).map(|cstr| cstr); + | ------------------------- ^^^^ + | | + | type must be known at this point + | +note: required for `SmallCString<_>` to implement `TryFrom<()>` + --> $DIR/issue-98299.rs:12:22 + | +LL | impl<const N: usize> TryFrom<()> for SmallCString<N> { + | -------------- ^^^^^^^^^^^ ^^^^^^^^^^^^^^^ + | | + | unsatisfied trait bound introduced here help: consider giving this closure parameter an explicit type, where the value of const parameter `N` is specified | LL | SmallCString::try_from(p).map(|cstr: SmallCString<N>| cstr); | +++++++++++++++++ -error: aborting due to 1 previous error +error: aborting due to 3 previous errors -For more information about this error, try `rustc --explain E0282`. +For more information about this error, try `rustc --explain E0284`. diff --git a/tests/ui/lifetimes/refcell-in-tail-expr.edition2021.stderr b/tests/ui/lifetimes/refcell-in-tail-expr.edition2021.stderr new file mode 100644 index 00000000000..858be42d540 --- /dev/null +++ b/tests/ui/lifetimes/refcell-in-tail-expr.edition2021.stderr @@ -0,0 +1,26 @@ +error[E0597]: `cell` does not live long enough + --> $DIR/refcell-in-tail-expr.rs:12:27 + | +LL | let cell = std::cell::RefCell::new(0u8); + | ---- binding `cell` declared here +LL | +LL | if let Ok(mut byte) = cell.try_borrow_mut() { + | ^^^^----------------- + | | + | borrowed value does not live long enough + | a temporary with access to the borrow is created here ... +... +LL | } + | - + | | + | `cell` dropped here while still borrowed + | ... and the borrow might be used here, when that temporary is dropped and runs the destructor for type `Result<RefMut<'_, u8>, BorrowMutError>` + | +help: consider adding semicolon after the expression so its temporaries are dropped sooner, before the local variables declared by the block are dropped + | +LL | }; + | + + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0597`. diff --git a/tests/ui/lifetimes/refcell-in-tail-expr.rs b/tests/ui/lifetimes/refcell-in-tail-expr.rs new file mode 100644 index 00000000000..b1814c1e327 --- /dev/null +++ b/tests/ui/lifetimes/refcell-in-tail-expr.rs @@ -0,0 +1,16 @@ +//@ revisions: edition2021 edition2024 +//@ [edition2021] edition: 2021 +//@ [edition2024] edition: 2024 +//@ [edition2024] compile-flags: -Zunstable-options +//@ [edition2024] check-pass + +#![cfg_attr(edition2024, feature(shorter_tail_lifetimes))] + +fn main() { + let cell = std::cell::RefCell::new(0u8); + + if let Ok(mut byte) = cell.try_borrow_mut() { + //[edition2021]~^ ERROR: `cell` does not live long enough + *byte = 1; + } +} diff --git a/tests/ui/lifetimes/shorter-tail-expr-lifetime.edition2021.stderr b/tests/ui/lifetimes/shorter-tail-expr-lifetime.edition2021.stderr new file mode 100644 index 00000000000..ad28ae2f80d --- /dev/null +++ b/tests/ui/lifetimes/shorter-tail-expr-lifetime.edition2021.stderr @@ -0,0 +1,26 @@ +error[E0597]: `c` does not live long enough + --> $DIR/shorter-tail-expr-lifetime.rs:10:5 + | +LL | let c = std::cell::RefCell::new(".."); + | - binding `c` declared here +LL | c.borrow().len() + | ^--------- + | | + | borrowed value does not live long enough + | a temporary with access to the borrow is created here ... +LL | } + | - + | | + | `c` dropped here while still borrowed + | ... and the borrow might be used here, when that temporary is dropped and runs the destructor for type `Ref<'_, &str>` + | + = note: the temporary is part of an expression at the end of a block; + consider forcing this temporary to be dropped sooner, before the block's local variables are dropped +help: for example, you could save the expression's value in a new local variable `x` and then make `x` be the expression at the end of the block + | +LL | let x = c.borrow().len(); x + | +++++++ +++ + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0597`. diff --git a/tests/ui/lifetimes/shorter-tail-expr-lifetime.rs b/tests/ui/lifetimes/shorter-tail-expr-lifetime.rs new file mode 100644 index 00000000000..0392b6c6d9a --- /dev/null +++ b/tests/ui/lifetimes/shorter-tail-expr-lifetime.rs @@ -0,0 +1,15 @@ +//@ revisions: edition2021 edition2024 +//@ [edition2024] compile-flags: -Zunstable-options +//@ [edition2024] edition: 2024 +//@ [edition2024] run-pass + +#![cfg_attr(edition2024, feature(shorter_tail_lifetimes))] + +fn f() -> usize { + let c = std::cell::RefCell::new(".."); + c.borrow().len() //[edition2021]~ ERROR: `c` does not live long enough +} + +fn main() { + let _ = f(); +} diff --git a/tests/ui/lifetimes/tail-expr-in-nested-expr.rs b/tests/ui/lifetimes/tail-expr-in-nested-expr.rs new file mode 100644 index 00000000000..a8989f22f4b --- /dev/null +++ b/tests/ui/lifetimes/tail-expr-in-nested-expr.rs @@ -0,0 +1,9 @@ +//@ edition: 2024 +//@ compile-flags: -Zunstable-options + +#![feature(shorter_tail_lifetimes)] + +fn main() { + let _ = { String::new().as_str() }.len(); + //~^ ERROR temporary value dropped while borrowed +} diff --git a/tests/ui/lifetimes/tail-expr-in-nested-expr.stderr b/tests/ui/lifetimes/tail-expr-in-nested-expr.stderr new file mode 100644 index 00000000000..f699d184bdb --- /dev/null +++ b/tests/ui/lifetimes/tail-expr-in-nested-expr.stderr @@ -0,0 +1,15 @@ +error[E0716]: temporary value dropped while borrowed + --> $DIR/tail-expr-in-nested-expr.rs:7:15 + | +LL | let _ = { String::new().as_str() }.len(); + | ^^^^^^^^^^^^^--------- + | | | + | | temporary value is freed at the end of this statement + | creates a temporary value which is freed while still in use + | borrow later used here + | + = note: consider using a `let` binding to create a longer lived value + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0716`. diff --git a/tests/ui/lifetimes/tail-expr-lock-poisoning.rs b/tests/ui/lifetimes/tail-expr-lock-poisoning.rs new file mode 100644 index 00000000000..cdfd35304b4 --- /dev/null +++ b/tests/ui/lifetimes/tail-expr-lock-poisoning.rs @@ -0,0 +1,30 @@ +//@ revisions: edition2021 edition2024 +//@ ignore-wasm no panic or subprocess support +//@ [edition2024] compile-flags: -Zunstable-options +//@ [edition2024] edition: 2024 +//@ run-pass +//@ needs-unwind +#![cfg_attr(edition2024, feature(shorter_tail_lifetimes))] + +use std::sync::Mutex; + +struct PanicOnDrop; +impl Drop for PanicOnDrop { + fn drop(&mut self) { + panic!() + } +} + +fn f(m: &Mutex<i32>) -> i32 { + let _x = PanicOnDrop; + *m.lock().unwrap() +} + +fn main() { + let m = Mutex::new(0); + let _ = std::panic::catch_unwind(|| f(&m)); + #[cfg(edition2024)] + assert!(m.lock().is_ok()); + #[cfg(edition2021)] + assert!(m.lock().is_err()); +} diff --git a/tests/ui/lint/dead-code/tuple-struct-field.rs b/tests/ui/lint/dead-code/tuple-struct-field.rs index d13fe029289..ff3da410500 100644 --- a/tests/ui/lint/dead-code/tuple-struct-field.rs +++ b/tests/ui/lint/dead-code/tuple-struct-field.rs @@ -5,15 +5,20 @@ use std::marker::PhantomData; const LEN: usize = 4; -struct SingleUnused(i32, [u8; LEN], String); -//~^ ERROR: field `1` is never read +struct UnusedAtTheEnd(i32, f32, [u8; LEN], String, u8); +//~^ ERROR:fields `1`, `2`, `3`, and `4` are never read +//~| NOTE: fields in this struct +//~| HELP: consider removing these fields + +struct UnusedJustOneField(i32); +//~^ ERROR: field `0` is never read //~| NOTE: field in this struct -//~| HELP: consider changing the field to be of unit type +//~| HELP: consider removing this field -struct MultipleUnused(i32, f32, String, u8); -//~^ ERROR: fields `0`, `1`, `2`, and `3` are never read +struct UnusedInTheMiddle(i32, f32, String, u8, u32); +//~^ ERROR: fields `1`, `2`, and `4` are never read //~| NOTE: fields in this struct -//~| HELP: consider changing the fields to be of unit type +//~| HELP: consider changing the fields to be of unit type to suppress this warning while preserving the field numbering, or remove the fields struct GoodUnit(()); @@ -23,15 +28,19 @@ struct Void; struct GoodVoid(Void); fn main() { - let w = SingleUnused(42, [0, 1, 2, 3], "abc".to_string()); - let _ = w.0; - let _ = w.2; + let u1 = UnusedAtTheEnd(42, 3.14, [0, 1, 2, 3], "def".to_string(), 4u8); + let _ = u1.0; + + let _ = UnusedJustOneField(42); + + let u2 = UnusedInTheMiddle(42, 3.14, "def".to_string(), 4u8, 5); + let _ = u2.0; + let _ = u2.3; - let m = MultipleUnused(42, 3.14, "def".to_string(), 4u8); let gu = GoodUnit(()); let gp = GoodPhantom(PhantomData); let gv = GoodVoid(Void); - let _ = (gu, gp, gv, m); + let _ = (gu, gp, gv); } diff --git a/tests/ui/lint/dead-code/tuple-struct-field.stderr b/tests/ui/lint/dead-code/tuple-struct-field.stderr index 0154d5489f9..434554d7ae5 100644 --- a/tests/ui/lint/dead-code/tuple-struct-field.stderr +++ b/tests/ui/lint/dead-code/tuple-struct-field.stderr @@ -1,33 +1,40 @@ -error: field `1` is never read - --> $DIR/tuple-struct-field.rs:8:26 +error: fields `1`, `2`, `3`, and `4` are never read + --> $DIR/tuple-struct-field.rs:8:28 | -LL | struct SingleUnused(i32, [u8; LEN], String); - | ------------ ^^^^^^^^^ +LL | struct UnusedAtTheEnd(i32, f32, [u8; LEN], String, u8); + | -------------- ^^^ ^^^^^^^^^ ^^^^^^ ^^ | | - | field in this struct + | fields in this struct | + = help: consider removing these fields note: the lint level is defined here --> $DIR/tuple-struct-field.rs:1:9 | LL | #![deny(dead_code)] | ^^^^^^^^^ -help: consider changing the field to be of unit type to suppress this warning while preserving the field numbering, or remove the field + +error: field `0` is never read + --> $DIR/tuple-struct-field.rs:13:27 + | +LL | struct UnusedJustOneField(i32); + | ------------------ ^^^ + | | + | field in this struct | -LL | struct SingleUnused(i32, (), String); - | ~~ + = help: consider removing this field -error: fields `0`, `1`, `2`, and `3` are never read - --> $DIR/tuple-struct-field.rs:13:23 +error: fields `1`, `2`, and `4` are never read + --> $DIR/tuple-struct-field.rs:18:31 | -LL | struct MultipleUnused(i32, f32, String, u8); - | -------------- ^^^ ^^^ ^^^^^^ ^^ +LL | struct UnusedInTheMiddle(i32, f32, String, u8, u32); + | ----------------- ^^^ ^^^^^^ ^^^ | | | fields in this struct | help: consider changing the fields to be of unit type to suppress this warning while preserving the field numbering, or remove the fields | -LL | struct MultipleUnused((), (), (), ()); - | ~~ ~~ ~~ ~~ +LL | struct UnusedInTheMiddle(i32, (), (), u8, ()); + | ~~ ~~ ~~ -error: aborting due to 2 previous errors +error: aborting due to 3 previous errors diff --git a/tests/ui/lint/expect-future_breakage-crash-issue-126521.rs b/tests/ui/lint/expect-future_breakage-crash-issue-126521.rs new file mode 100644 index 00000000000..0e622ff3aaf --- /dev/null +++ b/tests/ui/lint/expect-future_breakage-crash-issue-126521.rs @@ -0,0 +1,23 @@ +// This test covers similar crashes from both #126521 and #126751. + +macro_rules! foo { + ($val:ident) => { + true; + }; +} + +macro_rules! bar { + ($val:ident) => { + (5_i32.overflowing_sub(3)); + }; +} + +fn main() { + #[expect(semicolon_in_expressions_from_macros)] + //~^ ERROR the `#[expect]` attribute is an experimental feature + let _ = foo!(x); + + #[expect(semicolon_in_expressions_from_macros)] + //~^ ERROR the `#[expect]` attribute is an experimental feature + let _ = bar!(x); +} diff --git a/tests/ui/lint/expect-future_breakage-crash-issue-126521.stderr b/tests/ui/lint/expect-future_breakage-crash-issue-126521.stderr new file mode 100644 index 00000000000..994630ec23b --- /dev/null +++ b/tests/ui/lint/expect-future_breakage-crash-issue-126521.stderr @@ -0,0 +1,23 @@ +error[E0658]: the `#[expect]` attribute is an experimental feature + --> $DIR/expect-future_breakage-crash-issue-126521.rs:16:5 + | +LL | #[expect(semicolon_in_expressions_from_macros)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #54503 <https://github.com/rust-lang/rust/issues/54503> for more information + = help: add `#![feature(lint_reasons)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: the `#[expect]` attribute is an experimental feature + --> $DIR/expect-future_breakage-crash-issue-126521.rs:20:5 + | +LL | #[expect(semicolon_in_expressions_from_macros)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #54503 <https://github.com/rust-lang/rust/issues/54503> for more information + = help: add `#![feature(lint_reasons)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0658`. diff --git a/tests/ui/lint/non-local-defs/cargo-update.stderr b/tests/ui/lint/non-local-defs/cargo-update.stderr index afd37d03a23..bccf8622bac 100644 --- a/tests/ui/lint/non-local-defs/cargo-update.stderr +++ b/tests/ui/lint/non-local-defs/cargo-update.stderr @@ -12,7 +12,7 @@ LL | non_local_macro::non_local_impl!(LocalStruct); = note: the macro `non_local_macro::non_local_impl` may come from an old version of the `non_local_macro` crate, try updating your dependency with `cargo update -p non_local_macro` = note: `impl` may be usable in bounds, etc. from outside the expression, which might e.g. make something constructible that previously wasn't, because it's still on a publicly-visible type = note: an `impl` is never scoped, even when it is nested inside an item, as it may impact type checking outside of that item, which can be the case if neither the trait or the self type are at the same nesting level as the `impl` - = note: items in an anonymous const item (`const _: () = { ... }`) are treated as in the same scope as the anonymous const's declaration + = note: items in an anonymous const item (`const _: () = { ... }`) are treated as in the same scope as the anonymous const's declaration for the purpose of this lint = note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue <https://github.com/rust-lang/rust/issues/120363> = note: `#[warn(non_local_definitions)]` on by default = note: this warning originates in the macro `non_local_macro::non_local_impl` (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/tests/ui/lint/non-local-defs/consts.stderr b/tests/ui/lint/non-local-defs/consts.stderr index 2756ea40138..9f70119e0f8 100644 --- a/tests/ui/lint/non-local-defs/consts.stderr +++ b/tests/ui/lint/non-local-defs/consts.stderr @@ -15,7 +15,7 @@ LL | impl Uto for &Test {} | = note: `impl` may be usable in bounds, etc. from outside the expression, which might e.g. make something constructible that previously wasn't, because it's still on a publicly-visible type = note: an `impl` is never scoped, even when it is nested inside an item, as it may impact type checking outside of that item, which can be the case if neither the trait or the self type are at the same nesting level as the `impl` - = note: items in an anonymous const item (`const _: () = { ... }`) are treated as in the same scope as the anonymous const's declaration + = note: items in an anonymous const item (`const _: () = { ... }`) are treated as in the same scope as the anonymous const's declaration for the purpose of this lint = note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue <https://github.com/rust-lang/rust/issues/120363> = note: `#[warn(non_local_definitions)]` on by default @@ -32,7 +32,7 @@ LL | impl Uto2 for Test {} | = note: `impl` may be usable in bounds, etc. from outside the expression, which might e.g. make something constructible that previously wasn't, because it's still on a publicly-visible type = note: an `impl` is never scoped, even when it is nested inside an item, as it may impact type checking outside of that item, which can be the case if neither the trait or the self type are at the same nesting level as the `impl` - = note: items in an anonymous const item (`const _: () = { ... }`) are treated as in the same scope as the anonymous const's declaration + = note: items in an anonymous const item (`const _: () = { ... }`) are treated as in the same scope as the anonymous const's declaration for the purpose of this lint = note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue <https://github.com/rust-lang/rust/issues/120363> warning: non-local `impl` definition, `impl` blocks should be written at the same level as their item @@ -48,7 +48,7 @@ LL | impl Uto3 for Test {} | = note: `impl` may be usable in bounds, etc. from outside the expression, which might e.g. make something constructible that previously wasn't, because it's still on a publicly-visible type = note: an `impl` is never scoped, even when it is nested inside an item, as it may impact type checking outside of that item, which can be the case if neither the trait or the self type are at the same nesting level as the `impl` - = note: items in an anonymous const item (`const _: () = { ... }`) are treated as in the same scope as the anonymous const's declaration + = note: items in an anonymous const item (`const _: () = { ... }`) are treated as in the same scope as the anonymous const's declaration for the purpose of this lint = note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue <https://github.com/rust-lang/rust/issues/120363> warning: non-local `impl` definition, `impl` blocks should be written at the same level as their item @@ -94,7 +94,7 @@ LL | impl Test { | `Test` is not local | = note: methods and associated constants are still usable outside the current expression, only `impl Local` and `impl dyn Local` can ever be private, and only if the type is nested in the same item as the `impl` - = note: items in an anonymous const item (`const _: () = { ... }`) are treated as in the same scope as the anonymous const's declaration + = note: items in an anonymous const item (`const _: () = { ... }`) are treated as in the same scope as the anonymous const's declaration for the purpose of this lint = note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue <https://github.com/rust-lang/rust/issues/120363> warning: non-local `impl` definition, `impl` blocks should be written at the same level as their item diff --git a/tests/ui/macros/auxiliary/expr_2021_implicit.rs b/tests/ui/macros/auxiliary/expr_2021_implicit.rs new file mode 100644 index 00000000000..61762e41dee --- /dev/null +++ b/tests/ui/macros/auxiliary/expr_2021_implicit.rs @@ -0,0 +1,9 @@ +//@ edition:2021 + +#[macro_export] +macro_rules! m { + ($expr:expr) => { + compile_error!("did not expect an expression to be parsed"); + }; + (const { }) => {}; +} diff --git a/tests/ui/macros/expr_2021_implicit_in_2024.rs b/tests/ui/macros/expr_2021_implicit_in_2024.rs new file mode 100644 index 00000000000..b3f7a31a802 --- /dev/null +++ b/tests/ui/macros/expr_2021_implicit_in_2024.rs @@ -0,0 +1,12 @@ +//@ compile-flags: --edition=2024 -Zunstable-options +//@ aux-build:expr_2021_implicit.rs + +//@ check-pass + +extern crate expr_2021_implicit; + +// Makes sure that a `:expr` fragment matcher defined in a edition 2021 crate +// still parses like an `expr_2021` fragment matcher in a 2024 user crate. +expr_2021_implicit::m!(const {}); + +fn main() {} diff --git a/tests/ui/macros/expr_2021_old_edition.rs b/tests/ui/macros/expr_2021_old_edition.rs deleted file mode 100644 index a7711266106..00000000000 --- a/tests/ui/macros/expr_2021_old_edition.rs +++ /dev/null @@ -1,13 +0,0 @@ -//@ compile-flags: --edition=2018 - -// This test ensures that expr_2021 is not allowed on pre-2021 editions - -macro_rules! m { - ($e:expr_2021) => { //~ ERROR: invalid fragment specifier `expr_2021` - $e - }; -} - -fn main() { - m!(()); //~ ERROR: no rules expected the token `(` -} diff --git a/tests/ui/macros/expr_2021_old_edition.stderr b/tests/ui/macros/expr_2021_old_edition.stderr deleted file mode 100644 index bffa8a1ca17..00000000000 --- a/tests/ui/macros/expr_2021_old_edition.stderr +++ /dev/null @@ -1,26 +0,0 @@ -error: invalid fragment specifier `expr_2021` - --> $DIR/expr_2021_old_edition.rs:6:6 - | -LL | ($e:expr_2021) => { - | ^^^^^^^^^^^^ - | - = help: fragment specifier `expr_2021` requires Rust 2021 or later - valid fragment specifiers are `ident`, `block`, `stmt`, `expr`, `pat`, `ty`, `lifetime`, `literal`, `path`, `meta`, `tt`, `item` and `vis` - -error: no rules expected the token `(` - --> $DIR/expr_2021_old_edition.rs:12:8 - | -LL | macro_rules! m { - | -------------- when calling this macro -... -LL | m!(()); - | ^ no rules expected this token in macro call - | -note: while trying to match meta-variable `$e:ident` - --> $DIR/expr_2021_old_edition.rs:6:6 - | -LL | ($e:expr_2021) => { - | ^^^^^^^^^^^^ - -error: aborting due to 2 previous errors - diff --git a/tests/ui/nll/issue-52534-1.rs b/tests/ui/nll/issue-52534-1.rs index d9ea3ae42c4..526b81bb2d0 100644 --- a/tests/ui/nll/issue-52534-1.rs +++ b/tests/ui/nll/issue-52534-1.rs @@ -17,14 +17,14 @@ fn foo(x: &u32) -> &u32 { fn baz(x: &u32) -> &&u32 { let x = 22; &&x -//~^ ERROR cannot return value referencing local variable +//~^ ERROR cannot return value referencing local variable `x` //~| ERROR cannot return reference to temporary value } fn foobazbar<'a>(x: u32, y: &'a u32) -> &'a u32 { let x = 22; &x -//~^ ERROR cannot return reference to local variable +//~^ ERROR cannot return reference to local variable `x` } fn foobar<'a>(x: &'a u32) -> &'a u32 { diff --git a/tests/ui/or-patterns/bindings-runpass-2.rs b/tests/ui/or-patterns/bindings-runpass-2.rs index 657d7f1ed18..a9ae9981084 100644 --- a/tests/ui/or-patterns/bindings-runpass-2.rs +++ b/tests/ui/or-patterns/bindings-runpass-2.rs @@ -26,5 +26,6 @@ fn main() { assert_eq!(or_at(Err(7)), 207); assert_eq!(or_at(Err(8)), 8); assert_eq!(or_at(Err(20)), 220); + assert_eq!(or_at(Err(34)), 134); assert_eq!(or_at(Err(50)), 500); } diff --git a/tests/ui/or-patterns/inner-or-pat.or3.stderr b/tests/ui/or-patterns/inner-or-pat.or3.stderr index 10ec7c202e4..5c522a97cce 100644 --- a/tests/ui/or-patterns/inner-or-pat.or3.stderr +++ b/tests/ui/or-patterns/inner-or-pat.or3.stderr @@ -1,5 +1,5 @@ error[E0308]: mismatched types - --> $DIR/inner-or-pat.rs:38:54 + --> $DIR/inner-or-pat.rs:36:54 | LL | match x { | - this expression has type `&str` diff --git a/tests/ui/or-patterns/inner-or-pat.or4.stderr b/tests/ui/or-patterns/inner-or-pat.or4.stderr index 97800161d82..508520c8237 100644 --- a/tests/ui/or-patterns/inner-or-pat.or4.stderr +++ b/tests/ui/or-patterns/inner-or-pat.or4.stderr @@ -1,5 +1,5 @@ error[E0408]: variable `x` is not bound in all patterns - --> $DIR/inner-or-pat.rs:53:37 + --> $DIR/inner-or-pat.rs:51:37 | LL | (x @ "red" | (x @ "blue" | "red")) => { | - ^^^^^ pattern doesn't bind `x` diff --git a/tests/ui/or-patterns/inner-or-pat.rs b/tests/ui/or-patterns/inner-or-pat.rs index ceb0a8b3f79..4d136de0053 100644 --- a/tests/ui/or-patterns/inner-or-pat.rs +++ b/tests/ui/or-patterns/inner-or-pat.rs @@ -1,7 +1,5 @@ -//@ revisions: or1 or2 or3 or4 or5 +//@ revisions: or1 or3 or4 //@ [or1] run-pass -//@ [or2] run-pass -//@ [or5] run-pass #![allow(unreachable_patterns)] #![allow(unused_variables)] diff --git a/tests/ui/or-patterns/issue-70413-no-unreachable-pat-and-guard.rs b/tests/ui/or-patterns/issue-70413-no-unreachable-pat-and-guard.rs index 7d62364a6ae..76dc298a5c8 100644 --- a/tests/ui/or-patterns/issue-70413-no-unreachable-pat-and-guard.rs +++ b/tests/ui/or-patterns/issue-70413-no-unreachable-pat-and-guard.rs @@ -1,21 +1,20 @@ -//@ check-pass +//@ run-pass #![deny(unreachable_patterns)] fn main() { - match (3,42) { - (a,_) | (_,a) if a > 10 => {println!("{}", a)} - _ => () + match (3, 42) { + (a, _) | (_, a) if a > 10 => {} + _ => unreachable!(), } - match Some((3,42)) { - Some((a, _)) | Some((_, a)) if a > 10 => {println!("{}", a)} - _ => () - + match Some((3, 42)) { + Some((a, _)) | Some((_, a)) if a > 10 => {} + _ => unreachable!(), } - match Some((3,42)) { - Some((a, _) | (_, a)) if a > 10 => {println!("{}", a)} - _ => () + match Some((3, 42)) { + Some((a, _) | (_, a)) if a > 10 => {} + _ => unreachable!(), } } diff --git a/tests/ui/or-patterns/search-via-bindings.rs b/tests/ui/or-patterns/search-via-bindings.rs index a760112f1d4..42174bd7cef 100644 --- a/tests/ui/or-patterns/search-via-bindings.rs +++ b/tests/ui/or-patterns/search-via-bindings.rs @@ -42,6 +42,23 @@ fn search_old_style(target: (bool, bool, bool)) -> u32 { } } +// Check that a dummy or-pattern also leads to running the guard multiple times. +fn search_with_dummy(target: (bool, bool)) -> u32 { + let x = ((false, true), (false, true), ()); + let mut guard_count = 0; + match x { + ((a, _) | (_, a), (b, _) | (_, b), _ | _) + if { + guard_count += 1; + (a, b) == target + } => + { + guard_count + } + _ => unreachable!(), + } +} + fn main() { assert_eq!(search((false, false, false)), 1); assert_eq!(search((false, false, true)), 2); @@ -60,4 +77,9 @@ fn main() { assert_eq!(search_old_style((true, false, true)), 6); assert_eq!(search_old_style((true, true, false)), 7); assert_eq!(search_old_style((true, true, true)), 8); + + assert_eq!(search_with_dummy((false, false)), 1); + assert_eq!(search_with_dummy((false, true)), 3); + assert_eq!(search_with_dummy((true, false)), 5); + assert_eq!(search_with_dummy((true, true)), 7); } diff --git a/tests/ui/or-patterns/simplification_subtleties.rs b/tests/ui/or-patterns/simplification_subtleties.rs new file mode 100644 index 00000000000..a932bd531e6 --- /dev/null +++ b/tests/ui/or-patterns/simplification_subtleties.rs @@ -0,0 +1,11 @@ +//@ run-pass + +#[allow(unreachable_patterns)] +fn main() { + // Test that we don't naively sort the two `2`s together and confuse the failure paths. + match (1, true) { + (1 | 2, false | false) => unreachable!(), + (2, _) => unreachable!(), + _ => {} + } +} diff --git a/tests/ui/panics/abort-on-panic.rs b/tests/ui/panics/abort-on-panic.rs index 5736ecf8685..feccefb2537 100644 --- a/tests/ui/panics/abort-on-panic.rs +++ b/tests/ui/panics/abort-on-panic.rs @@ -4,7 +4,6 @@ //@[next] compile-flags: -Znext-solver #![allow(unused_must_use)] -#![feature(c_unwind)] #![feature(panic_always_abort)] // Since we mark some ABIs as "nounwind" to LLVM, we must make sure that // we never unwind through them. diff --git a/tests/ui/panics/panic-in-ffi.rs b/tests/ui/panics/panic-in-ffi.rs index 6f54acb3e04..88f45f9a871 100644 --- a/tests/ui/panics/panic-in-ffi.rs +++ b/tests/ui/panics/panic-in-ffi.rs @@ -7,7 +7,6 @@ //@ normalize-stderr-test: "(core/src/panicking\.rs):[0-9]+:[0-9]+" -> "$1:$$LINE:$$COL" //@ needs-unwind //@ ignore-emscripten "RuntimeError" junk in output -#![feature(c_unwind)] extern "C" fn panic_in_ffi() { panic!("Test"); diff --git a/tests/ui/panics/panic-in-ffi.run.stderr b/tests/ui/panics/panic-in-ffi.run.stderr index a92a66c57fd..596355399c8 100644 --- a/tests/ui/panics/panic-in-ffi.run.stderr +++ b/tests/ui/panics/panic-in-ffi.run.stderr @@ -1,4 +1,4 @@ -thread 'main' panicked at $DIR/panic-in-ffi.rs:13:5: +thread 'main' panicked at $DIR/panic-in-ffi.rs:12:5: Test note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace thread 'main' panicked at library/core/src/panicking.rs:$LINE:$COL: diff --git a/tests/ui/parser/attribute/attr-stmt-expr-attr-bad.rs b/tests/ui/parser/attribute/attr-stmt-expr-attr-bad.rs index d1950087c4c..26761a1d254 100644 --- a/tests/ui/parser/attribute/attr-stmt-expr-attr-bad.rs +++ b/tests/ui/parser/attribute/attr-stmt-expr-attr-bad.rs @@ -28,9 +28,9 @@ fn main() {} #[cfg(FALSE)] fn e() { let _ = move || #![attr] {foo}; } //~^ ERROR an inner attribute is not permitted in this context #[cfg(FALSE)] fn e() { let _ = #[attr] ..#[attr] 0; } -//~^ ERROR expected expression, found `..` +//~^ ERROR attributes are not allowed on range expressions starting with `..` #[cfg(FALSE)] fn e() { let _ = #[attr] ..; } -//~^ ERROR expected expression, found `..` +//~^ ERROR attributes are not allowed on range expressions starting with `..` #[cfg(FALSE)] fn e() { let _ = #[attr] &#![attr] 0; } //~^ ERROR an inner attribute is not permitted in this context #[cfg(FALSE)] fn e() { let _ = #[attr] &mut #![attr] 0; } diff --git a/tests/ui/parser/attribute/attr-stmt-expr-attr-bad.stderr b/tests/ui/parser/attribute/attr-stmt-expr-attr-bad.stderr index e46c591080d..3593c5182ce 100644 --- a/tests/ui/parser/attribute/attr-stmt-expr-attr-bad.stderr +++ b/tests/ui/parser/attribute/attr-stmt-expr-attr-bad.stderr @@ -119,17 +119,17 @@ LL | #[cfg(FALSE)] fn e() { let _ = move || #![attr] {foo}; } = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files = note: outer attributes, like `#[test]`, annotate the item following them -error: expected expression, found `..` +error: attributes are not allowed on range expressions starting with `..` --> $DIR/attr-stmt-expr-attr-bad.rs:30:40 | LL | #[cfg(FALSE)] fn e() { let _ = #[attr] ..#[attr] 0; } - | ^^ expected expression + | ^^ -error: expected expression, found `..` +error: attributes are not allowed on range expressions starting with `..` --> $DIR/attr-stmt-expr-attr-bad.rs:32:40 | LL | #[cfg(FALSE)] fn e() { let _ = #[attr] ..; } - | ^^ expected expression + | ^^ error: an inner attribute is not permitted in this context --> $DIR/attr-stmt-expr-attr-bad.rs:34:41 diff --git a/tests/ui/parser/diff-markers/enum-2.stderr b/tests/ui/parser/diff-markers/enum-2.stderr index 20e551c2f95..b76cf5d5a01 100644 --- a/tests/ui/parser/diff-markers/enum-2.stderr +++ b/tests/ui/parser/diff-markers/enum-2.stderr @@ -2,20 +2,25 @@ error: encountered diff marker --> $DIR/enum-2.rs:3:1 | LL | <<<<<<< HEAD - | ^^^^^^^ after this is the code before the merge + | ^^^^^^^ between this marker and `|||||||` is the code that we're merging into LL | x: u8, LL | ||||||| - | ------- + | ------- between this marker and `=======` is the base code (what the two refs diverged from) LL | z: (), LL | ======= - | ------- + | ------- between this marker and `>>>>>>>` is the incoming code LL | y: i8, LL | >>>>>>> branch - | ^^^^^^^ above this are the incoming code changes + | ^^^^^^^ this marker concludes the conflict region | - = help: if you're having merge conflicts after pulling new code, the top section is the code you already had and the bottom section is the remote code - = help: if you're in the middle of a rebase, the top section is the code being rebased onto and the bottom section is the code coming from the current commit being rebased - = note: for an explanation on these markers from the `git` documentation, visit <https://git-scm.com/book/en/v2/Git-Tools-Advanced-Merging#_checking_out_conflicts> + = note: conflict markers indicate that a merge was started but could not be completed due to merge conflicts + to resolve a conflict, keep only the code you want and then delete the lines containing conflict markers + = help: if you're having merge conflicts after pulling new code: + the top section is the code you already had and the bottom section is the remote code + if you're in the middle of a rebase: + the top section is the code being rebased onto and the bottom section is the code coming from the current commit being rebased + = note: for an explanation on these markers from the `git` documentation: + visit <https://git-scm.com/book/en/v2/Git-Tools-Advanced-Merging#_checking_out_conflicts> error: aborting due to 1 previous error diff --git a/tests/ui/parser/diff-markers/enum.stderr b/tests/ui/parser/diff-markers/enum.stderr index be94331dce5..0ce473bc702 100644 --- a/tests/ui/parser/diff-markers/enum.stderr +++ b/tests/ui/parser/diff-markers/enum.stderr @@ -2,17 +2,22 @@ error: encountered diff marker --> $DIR/enum.rs:2:1 | LL | <<<<<<< HEAD - | ^^^^^^^ after this is the code before the merge + | ^^^^^^^ between this marker and `=======` is the code that we're merging into LL | Foo(u8), LL | ======= - | ------- + | ------- between this marker and `>>>>>>>` is the incoming code LL | Bar(i8), LL | >>>>>>> branch - | ^^^^^^^ above this are the incoming code changes + | ^^^^^^^ this marker concludes the conflict region | - = help: if you're having merge conflicts after pulling new code, the top section is the code you already had and the bottom section is the remote code - = help: if you're in the middle of a rebase, the top section is the code being rebased onto and the bottom section is the code coming from the current commit being rebased - = note: for an explanation on these markers from the `git` documentation, visit <https://git-scm.com/book/en/v2/Git-Tools-Advanced-Merging#_checking_out_conflicts> + = note: conflict markers indicate that a merge was started but could not be completed due to merge conflicts + to resolve a conflict, keep only the code you want and then delete the lines containing conflict markers + = help: if you're having merge conflicts after pulling new code: + the top section is the code you already had and the bottom section is the remote code + if you're in the middle of a rebase: + the top section is the code being rebased onto and the bottom section is the code coming from the current commit being rebased + = note: for an explanation on these markers from the `git` documentation: + visit <https://git-scm.com/book/en/v2/Git-Tools-Advanced-Merging#_checking_out_conflicts> error: aborting due to 1 previous error diff --git a/tests/ui/parser/diff-markers/fn-arg.stderr b/tests/ui/parser/diff-markers/fn-arg.stderr index aabcb826c12..24521ffa626 100644 --- a/tests/ui/parser/diff-markers/fn-arg.stderr +++ b/tests/ui/parser/diff-markers/fn-arg.stderr @@ -2,17 +2,22 @@ error: encountered diff marker --> $DIR/fn-arg.rs:3:1 | LL | <<<<<<< HEAD - | ^^^^^^^ after this is the code before the merge + | ^^^^^^^ between this marker and `=======` is the code that we're merging into LL | x: u8, LL | ======= - | ------- + | ------- between this marker and `>>>>>>>` is the incoming code LL | x: i8, LL | >>>>>>> branch - | ^^^^^^^ above this are the incoming code changes + | ^^^^^^^ this marker concludes the conflict region | - = help: if you're having merge conflicts after pulling new code, the top section is the code you already had and the bottom section is the remote code - = help: if you're in the middle of a rebase, the top section is the code being rebased onto and the bottom section is the code coming from the current commit being rebased - = note: for an explanation on these markers from the `git` documentation, visit <https://git-scm.com/book/en/v2/Git-Tools-Advanced-Merging#_checking_out_conflicts> + = note: conflict markers indicate that a merge was started but could not be completed due to merge conflicts + to resolve a conflict, keep only the code you want and then delete the lines containing conflict markers + = help: if you're having merge conflicts after pulling new code: + the top section is the code you already had and the bottom section is the remote code + if you're in the middle of a rebase: + the top section is the code being rebased onto and the bottom section is the code coming from the current commit being rebased + = note: for an explanation on these markers from the `git` documentation: + visit <https://git-scm.com/book/en/v2/Git-Tools-Advanced-Merging#_checking_out_conflicts> error: aborting due to 1 previous error diff --git a/tests/ui/parser/diff-markers/item-with-attr.stderr b/tests/ui/parser/diff-markers/item-with-attr.stderr index eefb2792e90..432673cd551 100644 --- a/tests/ui/parser/diff-markers/item-with-attr.stderr +++ b/tests/ui/parser/diff-markers/item-with-attr.stderr @@ -2,17 +2,22 @@ error: encountered diff marker --> $DIR/item-with-attr.rs:2:1 | LL | <<<<<<< HEAD - | ^^^^^^^ after this is the code before the merge + | ^^^^^^^ between this marker and `=======` is the code that we're merging into LL | fn foo() {} LL | ======= - | ------- + | ------- between this marker and `>>>>>>>` is the incoming code LL | fn bar() {} LL | >>>>>>> branch - | ^^^^^^^ above this are the incoming code changes + | ^^^^^^^ this marker concludes the conflict region | - = help: if you're having merge conflicts after pulling new code, the top section is the code you already had and the bottom section is the remote code - = help: if you're in the middle of a rebase, the top section is the code being rebased onto and the bottom section is the code coming from the current commit being rebased - = note: for an explanation on these markers from the `git` documentation, visit <https://git-scm.com/book/en/v2/Git-Tools-Advanced-Merging#_checking_out_conflicts> + = note: conflict markers indicate that a merge was started but could not be completed due to merge conflicts + to resolve a conflict, keep only the code you want and then delete the lines containing conflict markers + = help: if you're having merge conflicts after pulling new code: + the top section is the code you already had and the bottom section is the remote code + if you're in the middle of a rebase: + the top section is the code being rebased onto and the bottom section is the code coming from the current commit being rebased + = note: for an explanation on these markers from the `git` documentation: + visit <https://git-scm.com/book/en/v2/Git-Tools-Advanced-Merging#_checking_out_conflicts> error: aborting due to 1 previous error diff --git a/tests/ui/parser/diff-markers/item.stderr b/tests/ui/parser/diff-markers/item.stderr index a3092ebfcfd..180c74e5d69 100644 --- a/tests/ui/parser/diff-markers/item.stderr +++ b/tests/ui/parser/diff-markers/item.stderr @@ -2,17 +2,22 @@ error: encountered diff marker --> $DIR/item.rs:1:1 | LL | <<<<<<< HEAD - | ^^^^^^^ after this is the code before the merge + | ^^^^^^^ between this marker and `=======` is the code that we're merging into LL | fn foo() {} LL | ======= - | ------- + | ------- between this marker and `>>>>>>>` is the incoming code LL | fn bar() {} LL | >>>>>>> branch - | ^^^^^^^ above this are the incoming code changes + | ^^^^^^^ this marker concludes the conflict region | - = help: if you're having merge conflicts after pulling new code, the top section is the code you already had and the bottom section is the remote code - = help: if you're in the middle of a rebase, the top section is the code being rebased onto and the bottom section is the code coming from the current commit being rebased - = note: for an explanation on these markers from the `git` documentation, visit <https://git-scm.com/book/en/v2/Git-Tools-Advanced-Merging#_checking_out_conflicts> + = note: conflict markers indicate that a merge was started but could not be completed due to merge conflicts + to resolve a conflict, keep only the code you want and then delete the lines containing conflict markers + = help: if you're having merge conflicts after pulling new code: + the top section is the code you already had and the bottom section is the remote code + if you're in the middle of a rebase: + the top section is the code being rebased onto and the bottom section is the code coming from the current commit being rebased + = note: for an explanation on these markers from the `git` documentation: + visit <https://git-scm.com/book/en/v2/Git-Tools-Advanced-Merging#_checking_out_conflicts> error: aborting due to 1 previous error diff --git a/tests/ui/parser/diff-markers/statement.stderr b/tests/ui/parser/diff-markers/statement.stderr index c6c6cae8765..6dccce4a48e 100644 --- a/tests/ui/parser/diff-markers/statement.stderr +++ b/tests/ui/parser/diff-markers/statement.stderr @@ -2,17 +2,22 @@ error: encountered diff marker --> $DIR/statement.rs:10:1 | LL | <<<<<<< HEAD - | ^^^^^^^ after this is the code before the merge + | ^^^^^^^ between this marker and `=======` is the code that we're merging into LL | S::foo(); LL | ======= - | ------- + | ------- between this marker and `>>>>>>>` is the incoming code LL | S::bar(); LL | >>>>>>> branch - | ^^^^^^^ above this are the incoming code changes + | ^^^^^^^ this marker concludes the conflict region | - = help: if you're having merge conflicts after pulling new code, the top section is the code you already had and the bottom section is the remote code - = help: if you're in the middle of a rebase, the top section is the code being rebased onto and the bottom section is the code coming from the current commit being rebased - = note: for an explanation on these markers from the `git` documentation, visit <https://git-scm.com/book/en/v2/Git-Tools-Advanced-Merging#_checking_out_conflicts> + = note: conflict markers indicate that a merge was started but could not be completed due to merge conflicts + to resolve a conflict, keep only the code you want and then delete the lines containing conflict markers + = help: if you're having merge conflicts after pulling new code: + the top section is the code you already had and the bottom section is the remote code + if you're in the middle of a rebase: + the top section is the code being rebased onto and the bottom section is the code coming from the current commit being rebased + = note: for an explanation on these markers from the `git` documentation: + visit <https://git-scm.com/book/en/v2/Git-Tools-Advanced-Merging#_checking_out_conflicts> error: aborting due to 1 previous error diff --git a/tests/ui/parser/diff-markers/struct-expr.stderr b/tests/ui/parser/diff-markers/struct-expr.stderr index bdea8c841c6..3733cdd3496 100644 --- a/tests/ui/parser/diff-markers/struct-expr.stderr +++ b/tests/ui/parser/diff-markers/struct-expr.stderr @@ -2,17 +2,22 @@ error: encountered diff marker --> $DIR/struct-expr.rs:6:1 | LL | <<<<<<< HEAD - | ^^^^^^^ after this is the code before the merge + | ^^^^^^^ between this marker and `=======` is the code that we're merging into LL | x: 42, LL | ======= - | ------- + | ------- between this marker and `>>>>>>>` is the incoming code LL | x: 0, LL | >>>>>>> branch - | ^^^^^^^ above this are the incoming code changes + | ^^^^^^^ this marker concludes the conflict region | - = help: if you're having merge conflicts after pulling new code, the top section is the code you already had and the bottom section is the remote code - = help: if you're in the middle of a rebase, the top section is the code being rebased onto and the bottom section is the code coming from the current commit being rebased - = note: for an explanation on these markers from the `git` documentation, visit <https://git-scm.com/book/en/v2/Git-Tools-Advanced-Merging#_checking_out_conflicts> + = note: conflict markers indicate that a merge was started but could not be completed due to merge conflicts + to resolve a conflict, keep only the code you want and then delete the lines containing conflict markers + = help: if you're having merge conflicts after pulling new code: + the top section is the code you already had and the bottom section is the remote code + if you're in the middle of a rebase: + the top section is the code being rebased onto and the bottom section is the code coming from the current commit being rebased + = note: for an explanation on these markers from the `git` documentation: + visit <https://git-scm.com/book/en/v2/Git-Tools-Advanced-Merging#_checking_out_conflicts> error: aborting due to 1 previous error diff --git a/tests/ui/parser/diff-markers/struct.stderr b/tests/ui/parser/diff-markers/struct.stderr index 749941290cb..44f8346613e 100644 --- a/tests/ui/parser/diff-markers/struct.stderr +++ b/tests/ui/parser/diff-markers/struct.stderr @@ -2,17 +2,22 @@ error: encountered diff marker --> $DIR/struct.rs:2:1 | LL | <<<<<<< HEAD - | ^^^^^^^ after this is the code before the merge + | ^^^^^^^ between this marker and `=======` is the code that we're merging into LL | x: u8, LL | ======= - | ------- + | ------- between this marker and `>>>>>>>` is the incoming code LL | x: i8, LL | >>>>>>> branch - | ^^^^^^^ above this are the incoming code changes + | ^^^^^^^ this marker concludes the conflict region | - = help: if you're having merge conflicts after pulling new code, the top section is the code you already had and the bottom section is the remote code - = help: if you're in the middle of a rebase, the top section is the code being rebased onto and the bottom section is the code coming from the current commit being rebased - = note: for an explanation on these markers from the `git` documentation, visit <https://git-scm.com/book/en/v2/Git-Tools-Advanced-Merging#_checking_out_conflicts> + = note: conflict markers indicate that a merge was started but could not be completed due to merge conflicts + to resolve a conflict, keep only the code you want and then delete the lines containing conflict markers + = help: if you're having merge conflicts after pulling new code: + the top section is the code you already had and the bottom section is the remote code + if you're in the middle of a rebase: + the top section is the code being rebased onto and the bottom section is the code coming from the current commit being rebased + = note: for an explanation on these markers from the `git` documentation: + visit <https://git-scm.com/book/en/v2/Git-Tools-Advanced-Merging#_checking_out_conflicts> error: aborting due to 1 previous error diff --git a/tests/ui/parser/diff-markers/trait-item.stderr b/tests/ui/parser/diff-markers/trait-item.stderr index f01bbe8ba03..4361542c774 100644 --- a/tests/ui/parser/diff-markers/trait-item.stderr +++ b/tests/ui/parser/diff-markers/trait-item.stderr @@ -2,17 +2,22 @@ error: encountered diff marker --> $DIR/trait-item.rs:2:1 | LL | <<<<<<< HEAD - | ^^^^^^^ after this is the code before the merge + | ^^^^^^^ between this marker and `=======` is the code that we're merging into LL | fn foo() {} LL | ======= - | ------- + | ------- between this marker and `>>>>>>>` is the incoming code LL | fn bar() {} LL | >>>>>>> branch - | ^^^^^^^ above this are the incoming code changes + | ^^^^^^^ this marker concludes the conflict region | - = help: if you're having merge conflicts after pulling new code, the top section is the code you already had and the bottom section is the remote code - = help: if you're in the middle of a rebase, the top section is the code being rebased onto and the bottom section is the code coming from the current commit being rebased - = note: for an explanation on these markers from the `git` documentation, visit <https://git-scm.com/book/en/v2/Git-Tools-Advanced-Merging#_checking_out_conflicts> + = note: conflict markers indicate that a merge was started but could not be completed due to merge conflicts + to resolve a conflict, keep only the code you want and then delete the lines containing conflict markers + = help: if you're having merge conflicts after pulling new code: + the top section is the code you already had and the bottom section is the remote code + if you're in the middle of a rebase: + the top section is the code being rebased onto and the bottom section is the code coming from the current commit being rebased + = note: for an explanation on these markers from the `git` documentation: + visit <https://git-scm.com/book/en/v2/Git-Tools-Advanced-Merging#_checking_out_conflicts> error: aborting due to 1 previous error diff --git a/tests/ui/parser/diff-markers/tuple-struct.stderr b/tests/ui/parser/diff-markers/tuple-struct.stderr index 8dae123c96d..7fda24ba485 100644 --- a/tests/ui/parser/diff-markers/tuple-struct.stderr +++ b/tests/ui/parser/diff-markers/tuple-struct.stderr @@ -2,17 +2,22 @@ error: encountered diff marker --> $DIR/tuple-struct.rs:2:1 | LL | <<<<<<< HEAD - | ^^^^^^^ after this is the code before the merge + | ^^^^^^^ between this marker and `=======` is the code that we're merging into LL | u8, LL | ======= - | ------- + | ------- between this marker and `>>>>>>>` is the incoming code LL | i8, LL | >>>>>>> branch - | ^^^^^^^ above this are the incoming code changes + | ^^^^^^^ this marker concludes the conflict region | - = help: if you're having merge conflicts after pulling new code, the top section is the code you already had and the bottom section is the remote code - = help: if you're in the middle of a rebase, the top section is the code being rebased onto and the bottom section is the code coming from the current commit being rebased - = note: for an explanation on these markers from the `git` documentation, visit <https://git-scm.com/book/en/v2/Git-Tools-Advanced-Merging#_checking_out_conflicts> + = note: conflict markers indicate that a merge was started but could not be completed due to merge conflicts + to resolve a conflict, keep only the code you want and then delete the lines containing conflict markers + = help: if you're having merge conflicts after pulling new code: + the top section is the code you already had and the bottom section is the remote code + if you're in the middle of a rebase: + the top section is the code being rebased onto and the bottom section is the code coming from the current commit being rebased + = note: for an explanation on these markers from the `git` documentation: + visit <https://git-scm.com/book/en/v2/Git-Tools-Advanced-Merging#_checking_out_conflicts> error: aborting due to 1 previous error diff --git a/tests/ui/parser/diff-markers/unclosed-delims-in-macro.stderr b/tests/ui/parser/diff-markers/unclosed-delims-in-macro.stderr index 6995b8e6f23..927821ddfae 100644 --- a/tests/ui/parser/diff-markers/unclosed-delims-in-macro.stderr +++ b/tests/ui/parser/diff-markers/unclosed-delims-in-macro.stderr @@ -2,17 +2,22 @@ error: encountered diff marker --> $DIR/unclosed-delims-in-macro.rs:2:1 | LL | <<<<<<< HEAD - | ^^^^^^^ after this is the code before the merge + | ^^^^^^^ between this marker and `=======` is the code that we're merging into ... LL | ======= - | ------- + | ------- between this marker and `>>>>>>>` is the incoming code LL | () { // LL | >>>>>>> 7a4f13c blah blah blah - | ^^^^^^^ above this are the incoming code changes + | ^^^^^^^ this marker concludes the conflict region | - = help: if you're having merge conflicts after pulling new code, the top section is the code you already had and the bottom section is the remote code - = help: if you're in the middle of a rebase, the top section is the code being rebased onto and the bottom section is the code coming from the current commit being rebased - = note: for an explanation on these markers from the `git` documentation, visit <https://git-scm.com/book/en/v2/Git-Tools-Advanced-Merging#_checking_out_conflicts> + = note: conflict markers indicate that a merge was started but could not be completed due to merge conflicts + to resolve a conflict, keep only the code you want and then delete the lines containing conflict markers + = help: if you're having merge conflicts after pulling new code: + the top section is the code you already had and the bottom section is the remote code + if you're in the middle of a rebase: + the top section is the code being rebased onto and the bottom section is the code coming from the current commit being rebased + = note: for an explanation on these markers from the `git` documentation: + visit <https://git-scm.com/book/en/v2/Git-Tools-Advanced-Merging#_checking_out_conflicts> error: aborting due to 1 previous error diff --git a/tests/ui/parser/diff-markers/unclosed-delims.rs b/tests/ui/parser/diff-markers/unclosed-delims.rs index 653a605c28c..7d400c3827b 100644 --- a/tests/ui/parser/diff-markers/unclosed-delims.rs +++ b/tests/ui/parser/diff-markers/unclosed-delims.rs @@ -2,13 +2,17 @@ mod tests { #[test] <<<<<<< HEAD //~^ ERROR encountered diff marker -//~| NOTE after this is the code before the merge +//~| NOTE between this marker and `=======` + +//~| NOTE conflict markers indicate that +//~| HELP if you're having merge conflicts //~| NOTE for an explanation on these markers + fn test1() { ======= -//~^ NOTE +//~^ NOTE between this marker and `>>>>>>>` fn test2() { >>>>>>> 7a4f13c blah blah blah -//~^ NOTE above this are the incoming code changes +//~^ NOTE this marker concludes the conflict region } } diff --git a/tests/ui/parser/diff-markers/unclosed-delims.stderr b/tests/ui/parser/diff-markers/unclosed-delims.stderr index d4636150e66..1eab96442b4 100644 --- a/tests/ui/parser/diff-markers/unclosed-delims.stderr +++ b/tests/ui/parser/diff-markers/unclosed-delims.stderr @@ -2,17 +2,22 @@ error: encountered diff marker --> $DIR/unclosed-delims.rs:3:1 | LL | <<<<<<< HEAD - | ^^^^^^^ after this is the code before the merge + | ^^^^^^^ between this marker and `=======` is the code that we're merging into ... LL | ======= - | ------- + | ------- between this marker and `>>>>>>>` is the incoming code ... LL | >>>>>>> 7a4f13c blah blah blah - | ^^^^^^^ above this are the incoming code changes + | ^^^^^^^ this marker concludes the conflict region | - = help: if you're having merge conflicts after pulling new code, the top section is the code you already had and the bottom section is the remote code - = help: if you're in the middle of a rebase, the top section is the code being rebased onto and the bottom section is the code coming from the current commit being rebased - = note: for an explanation on these markers from the `git` documentation, visit <https://git-scm.com/book/en/v2/Git-Tools-Advanced-Merging#_checking_out_conflicts> + = note: conflict markers indicate that a merge was started but could not be completed due to merge conflicts + to resolve a conflict, keep only the code you want and then delete the lines containing conflict markers + = help: if you're having merge conflicts after pulling new code: + the top section is the code you already had and the bottom section is the remote code + if you're in the middle of a rebase: + the top section is the code being rebased onto and the bottom section is the code coming from the current commit being rebased + = note: for an explanation on these markers from the `git` documentation: + visit <https://git-scm.com/book/en/v2/Git-Tools-Advanced-Merging#_checking_out_conflicts> error: aborting due to 1 previous error diff --git a/tests/ui/parser/diff-markers/use-statement.stderr b/tests/ui/parser/diff-markers/use-statement.stderr index 6d376166a7f..3eac7bebb5a 100644 --- a/tests/ui/parser/diff-markers/use-statement.stderr +++ b/tests/ui/parser/diff-markers/use-statement.stderr @@ -2,17 +2,22 @@ error: encountered diff marker --> $DIR/use-statement.rs:2:1 | LL | <<<<<<< HEAD - | ^^^^^^^ after this is the code before the merge + | ^^^^^^^ between this marker and `=======` is the code that we're merging into LL | bar, LL | ======= - | ------- + | ------- between this marker and `>>>>>>>` is the incoming code LL | baz, LL | >>>>>>> branch - | ^^^^^^^ above this are the incoming code changes + | ^^^^^^^ this marker concludes the conflict region | - = help: if you're having merge conflicts after pulling new code, the top section is the code you already had and the bottom section is the remote code - = help: if you're in the middle of a rebase, the top section is the code being rebased onto and the bottom section is the code coming from the current commit being rebased - = note: for an explanation on these markers from the `git` documentation, visit <https://git-scm.com/book/en/v2/Git-Tools-Advanced-Merging#_checking_out_conflicts> + = note: conflict markers indicate that a merge was started but could not be completed due to merge conflicts + to resolve a conflict, keep only the code you want and then delete the lines containing conflict markers + = help: if you're having merge conflicts after pulling new code: + the top section is the code you already had and the bottom section is the remote code + if you're in the middle of a rebase: + the top section is the code being rebased onto and the bottom section is the code coming from the current commit being rebased + = note: for an explanation on these markers from the `git` documentation: + visit <https://git-scm.com/book/en/v2/Git-Tools-Advanced-Merging#_checking_out_conflicts> error: aborting due to 1 previous error diff --git a/tests/ui/proc-macro/expr-stmt-nonterminal-tokens.stdout b/tests/ui/proc-macro/expr-stmt-nonterminal-tokens.stdout index 6523f2485cd..0168689b605 100644 --- a/tests/ui/proc-macro/expr-stmt-nonterminal-tokens.stdout +++ b/tests/ui/proc-macro/expr-stmt-nonterminal-tokens.stdout @@ -1,4 +1,4 @@ -PRINT-DERIVE INPUT (DISPLAY): enum E { V = { let _ = #[allow(warnings)] #[allow(warnings)] 0; 0 }, } +PRINT-DERIVE INPUT (DISPLAY): enum E { V = { let _ = #[allow(warnings)] 0; 0 }, } PRINT-DERIVE INPUT (DEBUG): TokenStream [ Ident { ident: "enum", @@ -64,31 +64,6 @@ PRINT-DERIVE INPUT (DEBUG): TokenStream [ ], span: #0 bytes(544..561), }, - Punct { - ch: '#', - spacing: Alone, - span: #0 bytes(543..544), - }, - Group { - delimiter: Bracket, - stream: TokenStream [ - Ident { - ident: "allow", - span: #0 bytes(545..550), - }, - Group { - delimiter: Parenthesis, - stream: TokenStream [ - Ident { - ident: "warnings", - span: #0 bytes(551..559), - }, - ], - span: #0 bytes(550..560), - }, - ], - span: #0 bytes(544..561), - }, Literal { kind: Integer, symbol: "0", diff --git a/tests/ui/resolve/path-attr-in-const-block.rs b/tests/ui/resolve/path-attr-in-const-block.rs new file mode 100644 index 00000000000..076511d26d6 --- /dev/null +++ b/tests/ui/resolve/path-attr-in-const-block.rs @@ -0,0 +1,9 @@ +// issue#126516 +// issue#126647 + +fn main() { + const { + #![path = foo!()] + //~^ ERROR: cannot find macro `foo` in this scope + } +} diff --git a/tests/ui/resolve/path-attr-in-const-block.stderr b/tests/ui/resolve/path-attr-in-const-block.stderr new file mode 100644 index 00000000000..8f9e58157c8 --- /dev/null +++ b/tests/ui/resolve/path-attr-in-const-block.stderr @@ -0,0 +1,8 @@ +error: cannot find macro `foo` in this scope + --> $DIR/path-attr-in-const-block.rs:6:19 + | +LL | #![path = foo!()] + | ^^^ + +error: aborting due to 1 previous error + diff --git a/tests/ui/return/return-ty-mismatch-note.rs b/tests/ui/return/return-ty-mismatch-note.rs index 352bc2a1637..36d590519fb 100644 --- a/tests/ui/return/return-ty-mismatch-note.rs +++ b/tests/ui/return/return-ty-mismatch-note.rs @@ -1,4 +1,5 @@ -// Checks existence of a note for "a caller chooses ty for ty param" upon return ty mismatch. +// Checks existence or absence of a note for "a caller chooses ty for ty param" upon return ty +// mismatch. fn f<T>() -> (T,) { (0,) //~ ERROR mismatched types @@ -14,6 +15,14 @@ fn h() -> u8 { 0u8 } +// This case was reported in <https://github.com/rust-lang/rust/issues/126547> where it doesn't +// make sense to make the "note caller chooses ty for ty param" note if the found type contains +// the ty param... +fn k<T>(_t: &T) -> T { + _t + //~^ ERROR mismatched types +} + fn main() { f::<()>(); g::<(), ()>; diff --git a/tests/ui/return/return-ty-mismatch-note.stderr b/tests/ui/return/return-ty-mismatch-note.stderr index 135903da5c2..47ef6863063 100644 --- a/tests/ui/return/return-ty-mismatch-note.stderr +++ b/tests/ui/return/return-ty-mismatch-note.stderr @@ -1,5 +1,5 @@ error[E0308]: mismatched types - --> $DIR/return-ty-mismatch-note.rs:4:6 + --> $DIR/return-ty-mismatch-note.rs:5:6 | LL | fn f<T>() -> (T,) { | - expected this type parameter @@ -10,7 +10,7 @@ LL | (0,) found type `{integer}` error[E0308]: mismatched types - --> $DIR/return-ty-mismatch-note.rs:8:6 + --> $DIR/return-ty-mismatch-note.rs:9:6 | LL | fn g<U, V>() -> (U, V) { | - expected this type parameter @@ -21,7 +21,7 @@ LL | (0, "foo") found type `{integer}` error[E0308]: mismatched types - --> $DIR/return-ty-mismatch-note.rs:8:9 + --> $DIR/return-ty-mismatch-note.rs:9:9 | LL | fn g<U, V>() -> (U, V) { | - expected this type parameter @@ -31,6 +31,19 @@ LL | (0, "foo") = note: expected type parameter `V` found reference `&'static str` -error: aborting due to 3 previous errors +error[E0308]: mismatched types + --> $DIR/return-ty-mismatch-note.rs:22:5 + | +LL | fn k<T>(_t: &T) -> T { + | - - expected `T` because of return type + | | + | expected this type parameter +LL | _t + | ^^ expected type parameter `T`, found `&T` + | + = note: expected type parameter `_` + found reference `&_` + +error: aborting due to 4 previous errors For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/const_derives/derive-const-use.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/const_derives/derive-const-use.stderr index e45c1a1f46f..86dfc521fea 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/const_derives/derive-const-use.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/const_derives/derive-const-use.stderr @@ -37,6 +37,19 @@ error[E0207]: the const parameter `host` is not constrained by the impl trait, s = note: expressions using a const parameter must map each value to a distinct output value = note: proving the result of expressions other than the parameter are unique is not supported +error[E0284]: type annotations needed + --> $DIR/derive-const-use.rs:18:35 + | +LL | const _: () = assert!(S((), A) == S::default()); + | ^^^^^^^^^^^^ cannot infer the value of the constant `_` + | +note: required for `S` to implement `Default` + --> $DIR/derive-const-use.rs:15:16 + | +LL | #[derive_const(Default, PartialEq)] + | ^^^^^^^ unsatisfied trait bound introduced in this `derive` macro + = note: this error originates in the derive macro `Default` (in Nightly builds, run with -Z macro-backtrace for more info) + error[E0308]: mismatched types --> $DIR/derive-const-use.rs:16:14 | @@ -49,7 +62,24 @@ LL | pub struct S((), A); found constant `true` = note: this error originates in the derive macro `PartialEq` (in Nightly builds, run with -Z macro-backtrace for more info) -error: aborting due to 6 previous errors +error[E0284]: type annotations needed + --> $DIR/derive-const-use.rs:16:18 + | +LL | #[derive_const(Default, PartialEq)] + | ------- in this derive macro expansion +LL | pub struct S((), A); + | ^ cannot infer the value of the constant `_` + | +note: required for `A` to implement `Default` + --> $DIR/derive-const-use.rs:7:12 + | +LL | impl const Default for A { + | ----- ^^^^^^^ ^ + | | + | unsatisfied trait bound introduced here + = note: this error originates in the derive macro `Default` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: aborting due to 8 previous errors -Some errors have detailed explanations: E0207, E0308, E0635. +Some errors have detailed explanations: E0207, E0284, E0308, E0635. For more information about an error, try `rustc --explain E0207`. diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/trait-default-body-stability.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/trait-default-body-stability.stderr index 62c4bc3b7ae..b58af6bb9d0 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/trait-default-body-stability.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/trait-default-body-stability.stderr @@ -34,6 +34,94 @@ LL | impl const FromResidual for T { = note: expressions using a const parameter must map each value to a distinct output value = note: proving the result of expressions other than the parameter are unique is not supported -error: aborting due to 4 previous errors +error[E0284]: type annotations needed + --> $DIR/trait-default-body-stability.rs:33:6 + | +LL | impl const FromResidual for T { + | ^^^^^ cannot infer the value of the constant `_` + | +note: required for `T` to implement `Try` + --> $DIR/trait-default-body-stability.rs:18:12 + | +LL | impl const Try for T { + | ----- ^^^ ^ + | | + | unsatisfied trait bound introduced here + +error[E0284]: type annotations needed + --> $DIR/trait-default-body-stability.rs:44:9 + | +LL | T? + | ^^ cannot infer the value of the constant `_` + | +note: required for `T` to implement `Try` + --> $DIR/trait-default-body-stability.rs:18:12 + | +LL | impl const Try for T { + | ----- ^^^ ^ + | | + | unsatisfied trait bound introduced here + +error[E0284]: type annotations needed + --> $DIR/trait-default-body-stability.rs:44:9 + | +LL | T? + | ^^ cannot infer the value of the constant `_` + | +note: required for `T` to implement `FromResidual<T>` + --> $DIR/trait-default-body-stability.rs:33:12 + | +LL | impl const FromResidual for T { + | ----- ^^^^^^^^^^^^ ^ + | | + | unsatisfied trait bound introduced here + +error[E0284]: type annotations needed + --> $DIR/trait-default-body-stability.rs:44:9 + | +LL | T? + | ^^ cannot infer the value of the constant `_` + | +note: required for `T` to implement `Try` + --> $DIR/trait-default-body-stability.rs:18:12 + | +LL | impl const Try for T { + | ----- ^^^ ^ + | | + | unsatisfied trait bound introduced here + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +error[E0284]: type annotations needed + --> $DIR/trait-default-body-stability.rs:44:9 + | +LL | T? + | ^^ cannot infer the value of the constant `_` + | +note: required for `T` to implement `FromResidual<T>` + --> $DIR/trait-default-body-stability.rs:33:12 + | +LL | impl const FromResidual for T { + | ----- ^^^^^^^^^^^^ ^ + | | + | unsatisfied trait bound introduced here + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +error[E0284]: type annotations needed + --> $DIR/trait-default-body-stability.rs:44:9 + | +LL | T? + | ^^ cannot infer the value of the constant `_` + | +note: required for `T` to implement `Try` + --> $DIR/trait-default-body-stability.rs:18:12 + | +LL | impl const Try for T { + | ----- ^^^ ^ + | | + | unsatisfied trait bound introduced here + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +error: aborting due to 10 previous errors -For more information about this error, try `rustc --explain E0207`. +Some errors have detailed explanations: E0207, E0284. +For more information about an error, try `rustc --explain E0207`. diff --git a/tests/ui/sized/ensure-overriding-bindings-in-pattern-with-ty-err-doesnt-ice.rs b/tests/ui/sized/ensure-overriding-bindings-in-pattern-with-ty-err-doesnt-ice.rs index 196da30b864..d0bf5078165 100644 --- a/tests/ui/sized/ensure-overriding-bindings-in-pattern-with-ty-err-doesnt-ice.rs +++ b/tests/ui/sized/ensure-overriding-bindings-in-pattern-with-ty-err-doesnt-ice.rs @@ -4,4 +4,5 @@ fn main() { //~| ERROR cannot find type `T` in this scope //~| ERROR const and type arguments are not allowed on builtin type `str` //~| ERROR expected unit struct, unit variant or constant, found associated function `str< +//~| ERROR type annotations needed } diff --git a/tests/ui/sized/ensure-overriding-bindings-in-pattern-with-ty-err-doesnt-ice.stderr b/tests/ui/sized/ensure-overriding-bindings-in-pattern-with-ty-err-doesnt-ice.stderr index 99f8dbd9a6c..fc431eb1412 100644 --- a/tests/ui/sized/ensure-overriding-bindings-in-pattern-with-ty-err-doesnt-ice.stderr +++ b/tests/ui/sized/ensure-overriding-bindings-in-pattern-with-ty-err-doesnt-ice.stderr @@ -32,7 +32,18 @@ error[E0533]: expected unit struct, unit variant or constant, found associated f LL | let str::<{fn str() { let str::T>>::as_bytes; }}, T>::as_bytes; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not a unit struct, unit variant or constant -error: aborting due to 4 previous errors +error[E0282]: type annotations needed + --> $DIR/ensure-overriding-bindings-in-pattern-with-ty-err-doesnt-ice.rs:2:31 + | +LL | let str::<{fn str() { let str::T>>::as_bytes; }}, T>::as_bytes; + | ^^^^^^^^^^^^^^^^^^ + | +help: consider giving this pattern a type + | +LL | let str::<{fn str() { let str::T>>::as_bytes: /* Type */; }}, T>::as_bytes; + | ++++++++++++ + +error: aborting due to 5 previous errors -Some errors have detailed explanations: E0109, E0412, E0533. +Some errors have detailed explanations: E0109, E0282, E0412, E0533. For more information about an error, try `rustc --explain E0109`. diff --git a/tests/ui/specialization/default-proj-ty-as-type-of-const-issue-125757.stderr b/tests/ui/specialization/default-proj-ty-as-type-of-const-issue-125757.stderr index b4c14c2294e..71d4277275f 100644 --- a/tests/ui/specialization/default-proj-ty-as-type-of-const-issue-125757.stderr +++ b/tests/ui/specialization/default-proj-ty-as-type-of-const-issue-125757.stderr @@ -14,11 +14,11 @@ LL | impl<const C: usize> Wrapper<C> {} | = help: consider constraining the associated type `<i32 as Trait>::Type` to `usize` = note: for more information, visit https://doc.rust-lang.org/book/ch19-03-advanced-traits.html -note: required by a bound in `Wrapper` +note: required by a const generic parameter in `Wrapper` --> $DIR/default-proj-ty-as-type-of-const-issue-125757.rs:12:16 | LL | struct Wrapper<const C: <i32 as Trait>::Type> {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `Wrapper` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this const generic parameter in `Wrapper` error[E0308]: mismatched types --> $DIR/default-proj-ty-as-type-of-const-issue-125757.rs:15:30 diff --git a/tests/ui/suggestions/clone-on-unconstrained-borrowed-type-param.stderr b/tests/ui/suggestions/clone-on-unconstrained-borrowed-type-param.stderr index 2c4be26a82b..afbb9c32d51 100644 --- a/tests/ui/suggestions/clone-on-unconstrained-borrowed-type-param.stderr +++ b/tests/ui/suggestions/clone-on-unconstrained-borrowed-type-param.stderr @@ -10,7 +10,6 @@ LL | t.clone() | = note: expected type parameter `_` found reference `&_` - = note: the caller chooses a type for `T` which can be different from `&T` note: `T` does not implement `Clone`, so `&T` was cloned instead --> $DIR/clone-on-unconstrained-borrowed-type-param.rs:3:5 | diff --git a/tests/ui/traits/item-privacy.stderr b/tests/ui/traits/item-privacy.stderr index d313f5af806..fd474fac155 100644 --- a/tests/ui/traits/item-privacy.stderr +++ b/tests/ui/traits/item-privacy.stderr @@ -8,10 +8,7 @@ LL | S.a(); | ^ | = help: items from traits can only be used if the trait is implemented and in scope -help: trait `A` which provides `a` is implemented but not in scope; perhaps you want to import it - | -LL + use method::A; - | + = help: trait `method::A` which provides `a` is implemented but not reachable help: there is a method `b` with a similar name | LL | S.b(); @@ -58,15 +55,12 @@ LL | S::a(&S); | ^ function or associated item not found in `S` | = help: items from traits can only be used if the trait is implemented and in scope + = help: trait `method::A` which provides `a` is implemented but not reachable help: there is an associated constant `B` with a similar name --> $DIR/item-privacy.rs:29:9 | LL | const B: u8 = 0; | ^^^^^^^^^^^ -help: trait `A` which provides `a` is implemented but not in scope; perhaps you want to import it - | -LL + use method::A; - | error[E0599]: no function or associated item named `b` found for struct `S` in the current scope --> $DIR/item-privacy.rs:80:8 @@ -107,10 +101,7 @@ LL | S::A; | ^ associated item not found in `S` | = help: items from traits can only be used if the trait is implemented and in scope -help: trait `A` which provides `A` is implemented but not in scope; perhaps you want to import it - | -LL + use assoc_const::A; - | + = help: trait `assoc_const::A` which provides `A` is implemented but not reachable help: there is an associated constant `B` with a similar name | LL | S::B; diff --git a/tests/ui/traits/next-solver/issue-118950-root-region.stderr b/tests/ui/traits/next-solver/issue-118950-root-region.stderr index 04c44276195..17da1f52479 100644 --- a/tests/ui/traits/next-solver/issue-118950-root-region.stderr +++ b/tests/ui/traits/next-solver/issue-118950-root-region.stderr @@ -25,10 +25,10 @@ help: this trait has no implementations, consider adding one LL | trait ToUnit<'a> { | ^^^^^^^^^^^^^^^^ - WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: AliasTy { args: ['^0.Named(DefId(0:15 ~ issue_118950_root_region[d54f]::{impl#1}::'a), "'a"), ?1t], def_id: DefId(0:8 ~ issue_118950_root_region[d54f]::Assoc), _use_alias_ty_new_instead: () } - WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: AliasTy { args: ['^0.Named(DefId(0:15 ~ issue_118950_root_region[d54f]::{impl#1}::'a), "'a"), ?1t], def_id: DefId(0:8 ~ issue_118950_root_region[d54f]::Assoc), _use_alias_ty_new_instead: () } - WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: AliasTy { args: ['^0.Named(DefId(0:15 ~ issue_118950_root_region[d54f]::{impl#1}::'a), "'a"), ?1t], def_id: DefId(0:8 ~ issue_118950_root_region[d54f]::Assoc), _use_alias_ty_new_instead: () } - WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: AliasTy { args: ['^0.Named(DefId(0:15 ~ issue_118950_root_region[d54f]::{impl#1}::'a), "'a"), ?1t], def_id: DefId(0:8 ~ issue_118950_root_region[d54f]::Assoc), _use_alias_ty_new_instead: () } + WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: AliasTy { args: ['^0.Named(DefId(0:15 ~ issue_118950_root_region[d54f]::{impl#1}::'a), "'a"), ?1t], def_id: DefId(0:8 ~ issue_118950_root_region[d54f]::Assoc) } + WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: AliasTy { args: ['^0.Named(DefId(0:15 ~ issue_118950_root_region[d54f]::{impl#1}::'a), "'a"), ?1t], def_id: DefId(0:8 ~ issue_118950_root_region[d54f]::Assoc) } + WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: AliasTy { args: ['^0.Named(DefId(0:15 ~ issue_118950_root_region[d54f]::{impl#1}::'a), "'a"), ?1t], def_id: DefId(0:8 ~ issue_118950_root_region[d54f]::Assoc) } + WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: AliasTy { args: ['^0.Named(DefId(0:15 ~ issue_118950_root_region[d54f]::{impl#1}::'a), "'a"), ?1t], def_id: DefId(0:8 ~ issue_118950_root_region[d54f]::Assoc) } error[E0119]: conflicting implementations of trait `Overlap<fn(_)>` for type `fn(_)` --> $DIR/issue-118950-root-region.rs:19:1 | diff --git a/tests/ui/transmutability/enums/uninhabited_optimization.rs b/tests/ui/transmutability/enums/uninhabited_optimization.rs index 04a8eb40c8b..c2d5b67ab2c 100644 --- a/tests/ui/transmutability/enums/uninhabited_optimization.rs +++ b/tests/ui/transmutability/enums/uninhabited_optimization.rs @@ -19,8 +19,14 @@ enum SingleUninhabited { Y(Uninhabited), } +enum MultipleUninhabited { + X(u8, Uninhabited), + Y(Uninhabited, u16), +} + fn main() { assert_transmutable::<Uninhabited>(); assert_transmutable::<SingleInhabited>(); assert_transmutable::<SingleUninhabited>(); + assert_transmutable::<MultipleUninhabited>(); } diff --git a/tests/ui/transmutability/issue-101739-1.stderr b/tests/ui/transmutability/issue-101739-1.stderr index 1df7c3e2f97..6f79bf7b424 100644 --- a/tests/ui/transmutability/issue-101739-1.stderr +++ b/tests/ui/transmutability/issue-101739-1.stderr @@ -10,7 +10,7 @@ error: the constant `ASSUME_ALIGNMENT` is not of type `Assume` LL | Dst: BikeshedIntrinsicFrom<Src, ASSUME_ALIGNMENT>, | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `Assume`, found `bool` | -note: required by a bound in `BikeshedIntrinsicFrom` +note: required by a const generic parameter in `BikeshedIntrinsicFrom` --> $SRC_DIR/core/src/mem/transmutability.rs:LL:COL error[E0308]: mismatched types diff --git a/tests/ui/transmutability/uninhabited.rs b/tests/ui/transmutability/uninhabited.rs index b61b110f6a1..7524922c16a 100644 --- a/tests/ui/transmutability/uninhabited.rs +++ b/tests/ui/transmutability/uninhabited.rs @@ -30,7 +30,7 @@ fn void() { } // Non-ZST uninhabited types are, nonetheless, uninhabited. -fn yawning_void() { +fn yawning_void_struct() { enum Void {} struct YawningVoid(Void, u128); @@ -49,6 +49,28 @@ fn yawning_void() { assert::is_maybe_transmutable::<(), Void>(); //~ ERROR: cannot be safely transmuted } +// Non-ZST uninhabited types are, nonetheless, uninhabited. +fn yawning_void_enum() { + enum Void {} + + enum YawningVoid { + A(Void, u128), + } + + const _: () = { + assert!(std::mem::size_of::<YawningVoid>() == std::mem::size_of::<u128>()); + // Just to be sure the above constant actually evaluated: + assert!(false); //~ ERROR: evaluation of constant value failed + }; + + // This transmutation is vacuously acceptable; since one cannot construct a + // `Void`, unsoundness cannot directly arise from transmuting a void into + // anything else. + assert::is_maybe_transmutable::<YawningVoid, u128>(); + + assert::is_maybe_transmutable::<(), Void>(); //~ ERROR: cannot be safely transmuted +} + // References to uninhabited types are, logically, uninhabited, but for layout // purposes are not ZSTs, and aren't treated as uninhabited when they appear in // enum variants. diff --git a/tests/ui/transmutability/uninhabited.stderr b/tests/ui/transmutability/uninhabited.stderr index 60219b0f263..88a98c798fc 100644 --- a/tests/ui/transmutability/uninhabited.stderr +++ b/tests/ui/transmutability/uninhabited.stderr @@ -7,10 +7,18 @@ LL | assert!(false); = note: this error originates in the macro `assert` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0080]: evaluation of constant value failed - --> $DIR/uninhabited.rs:65:9 + --> $DIR/uninhabited.rs:63:9 | LL | assert!(false); - | ^^^^^^^^^^^^^^ the evaluated program panicked at 'assertion failed: false', $DIR/uninhabited.rs:65:9 + | ^^^^^^^^^^^^^^ the evaluated program panicked at 'assertion failed: false', $DIR/uninhabited.rs:63:9 + | + = note: this error originates in the macro `assert` (in Nightly builds, run with -Z macro-backtrace for more info) + +error[E0080]: evaluation of constant value failed + --> $DIR/uninhabited.rs:87:9 + | +LL | assert!(false); + | ^^^^^^^^^^^^^^ the evaluated program panicked at 'assertion failed: false', $DIR/uninhabited.rs:87:9 | = note: this error originates in the macro `assert` (in Nightly builds, run with -Z macro-backtrace for more info) @@ -36,11 +44,33 @@ LL | | } LL | | }> | |__________^ required by this bound in `is_maybe_transmutable` -error[E0277]: `()` cannot be safely transmuted into `yawning_void::Void` +error[E0277]: `()` cannot be safely transmuted into `yawning_void_struct::Void` --> $DIR/uninhabited.rs:49:41 | LL | assert::is_maybe_transmutable::<(), Void>(); - | ^^^^ `yawning_void::Void` is uninhabited + | ^^^^ `yawning_void_struct::Void` is uninhabited + | +note: required by a bound in `is_maybe_transmutable` + --> $DIR/uninhabited.rs:10:14 + | +LL | pub fn is_maybe_transmutable<Src, Dst>() + | --------------------- required by a bound in this function +LL | where +LL | Dst: BikeshedIntrinsicFrom<Src, { + | ______________^ +LL | | Assume { +LL | | alignment: true, +LL | | lifetimes: true, +... | +LL | | } +LL | | }> + | |__________^ required by this bound in `is_maybe_transmutable` + +error[E0277]: `()` cannot be safely transmuted into `yawning_void_enum::Void` + --> $DIR/uninhabited.rs:71:41 + | +LL | assert::is_maybe_transmutable::<(), Void>(); + | ^^^^ `yawning_void_enum::Void` is uninhabited | note: required by a bound in `is_maybe_transmutable` --> $DIR/uninhabited.rs:10:14 @@ -59,7 +89,7 @@ LL | | }> | |__________^ required by this bound in `is_maybe_transmutable` error[E0277]: `u128` cannot be safely transmuted into `DistantVoid` - --> $DIR/uninhabited.rs:70:43 + --> $DIR/uninhabited.rs:92:43 | LL | assert::is_maybe_transmutable::<u128, DistantVoid>(); | ^^^^^^^^^^^ at least one value of `u128` isn't a bit-valid value of `DistantVoid` @@ -80,7 +110,7 @@ LL | | } LL | | }> | |__________^ required by this bound in `is_maybe_transmutable` -error: aborting due to 5 previous errors +error: aborting due to 7 previous errors Some errors have detailed explanations: E0080, E0277. For more information about an error, try `rustc --explain E0080`. diff --git a/tests/ui/type-alias-impl-trait/different_args_considered_equal.rs b/tests/ui/type-alias-impl-trait/different_args_considered_equal.rs new file mode 100644 index 00000000000..8ce471e3956 --- /dev/null +++ b/tests/ui/type-alias-impl-trait/different_args_considered_equal.rs @@ -0,0 +1,14 @@ +#![feature(type_alias_impl_trait)] + +pub type Opaque<'a> = impl Sized; + +fn get_one<'a>(a: *mut &'a str) -> Opaque<'a> { + a +} + +fn get_iter<'a>() -> impl IntoIterator<Item = Opaque<'a>> { + //~^ ERROR: item does not constrain + None::<Opaque<'static>> +} + +fn main() {} diff --git a/tests/ui/type-alias-impl-trait/different_args_considered_equal.stderr b/tests/ui/type-alias-impl-trait/different_args_considered_equal.stderr new file mode 100644 index 00000000000..f27f2234525 --- /dev/null +++ b/tests/ui/type-alias-impl-trait/different_args_considered_equal.stderr @@ -0,0 +1,15 @@ +error: item does not constrain `Opaque::{opaque#0}`, but has it in its signature + --> $DIR/different_args_considered_equal.rs:9:4 + | +LL | fn get_iter<'a>() -> impl IntoIterator<Item = Opaque<'a>> { + | ^^^^^^^^ + | + = note: consider moving the opaque type's declaration and defining uses into a separate module +note: this opaque type is in the signature + --> $DIR/different_args_considered_equal.rs:3:23 + | +LL | pub type Opaque<'a> = impl Sized; + | ^^^^^^^^^^ + +error: aborting due to 1 previous error + diff --git a/tests/ui/type-alias-impl-trait/different_args_considered_equal2.rs b/tests/ui/type-alias-impl-trait/different_args_considered_equal2.rs new file mode 100644 index 00000000000..43dfea97e6d --- /dev/null +++ b/tests/ui/type-alias-impl-trait/different_args_considered_equal2.rs @@ -0,0 +1,14 @@ +#![feature(type_alias_impl_trait)] + +pub type Opaque<'a> = impl Sized; + +fn get_one<'a>(a: *mut &'a str) -> impl IntoIterator<Item = Opaque<'a>> { + if a.is_null() { + Some(a) + } else { + None::<Opaque<'static>> + //~^ ERROR hidden type for `Opaque<'static>` captures lifetime that does not appear in bounds + } +} + +fn main() {} diff --git a/tests/ui/type-alias-impl-trait/different_args_considered_equal2.stderr b/tests/ui/type-alias-impl-trait/different_args_considered_equal2.stderr new file mode 100644 index 00000000000..1104c2c498a --- /dev/null +++ b/tests/ui/type-alias-impl-trait/different_args_considered_equal2.stderr @@ -0,0 +1,20 @@ +error[E0700]: hidden type for `Opaque<'static>` captures lifetime that does not appear in bounds + --> $DIR/different_args_considered_equal2.rs:9:9 + | +LL | pub type Opaque<'a> = impl Sized; + | ---------- opaque type defined here +LL | +LL | fn get_one<'a>(a: *mut &'a str) -> impl IntoIterator<Item = Opaque<'a>> { + | -- hidden type `*mut &'a str` captures the lifetime `'a` as defined here +... +LL | None::<Opaque<'static>> + | ^^^^^^^^^^^^^^^^^^^^^^^ + | +help: to declare that `impl IntoIterator<Item = Opaque<'a>>` captures `'a`, you can add an explicit `'a` lifetime bound + | +LL | fn get_one<'a>(a: *mut &'a str) -> impl IntoIterator<Item = Opaque<'a>> + 'a { + | ++++ + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0700`. diff --git a/tests/ui/type-alias-impl-trait/different_args_considered_equal3.rs b/tests/ui/type-alias-impl-trait/different_args_considered_equal3.rs new file mode 100644 index 00000000000..ea69175ba31 --- /dev/null +++ b/tests/ui/type-alias-impl-trait/different_args_considered_equal3.rs @@ -0,0 +1,22 @@ +//! Test that we don't allow coercing an opaque type with a non-static +//! lifetime to one with a static lifetime. While `get_iter` looks like +//! it would be doing the opposite, the way we're handling projections +//! makes `Opaque<'a>` the hidden type of `Opaque<'static>`. + +#![feature(type_alias_impl_trait)] + +mod defining_scope { + pub type Opaque<'a> = impl Sized; + + fn get_one<'a>(a: *mut &'a str) -> Opaque<'a> { + a + } +} +use defining_scope::Opaque; + +fn get_iter<'a>() -> impl IntoIterator<Item = Opaque<'a>> { + None::<Opaque<'static>> + //~^ ERROR lifetime may not live long enough +} + +fn main() {} diff --git a/tests/ui/type-alias-impl-trait/different_args_considered_equal3.stderr b/tests/ui/type-alias-impl-trait/different_args_considered_equal3.stderr new file mode 100644 index 00000000000..d8f70e3d778 --- /dev/null +++ b/tests/ui/type-alias-impl-trait/different_args_considered_equal3.stderr @@ -0,0 +1,10 @@ +error: lifetime may not live long enough + --> $DIR/different_args_considered_equal3.rs:18:5 + | +LL | fn get_iter<'a>() -> impl IntoIterator<Item = Opaque<'a>> { + | -- lifetime `'a` defined here +LL | None::<Opaque<'static>> + | ^^^^^^^^^^^^^^^^^^^^^^^ returning this value requires that `'a` must outlive `'static` + +error: aborting due to 1 previous error + diff --git a/tests/ui/type-alias-impl-trait/lazy_subtyping_of_opaques.rs b/tests/ui/type-alias-impl-trait/lazy_subtyping_of_opaques.rs index 72a90287e37..1bc352041a5 100644 --- a/tests/ui/type-alias-impl-trait/lazy_subtyping_of_opaques.rs +++ b/tests/ui/type-alias-impl-trait/lazy_subtyping_of_opaques.rs @@ -7,9 +7,10 @@ type Tait = impl FnOnce() -> (); fn reify_as_tait() -> Thunk<Tait> { + //~^ ERROR: expected a `FnOnce()` closure, found `()` Thunk::new(|cont| cont) //~^ ERROR: mismatched types - //~| ERROR: mismatched types + //~| ERROR: expected a `FnOnce()` closure, found `()` } struct Thunk<F>(F); diff --git a/tests/ui/type-alias-impl-trait/lazy_subtyping_of_opaques.stderr b/tests/ui/type-alias-impl-trait/lazy_subtyping_of_opaques.stderr index 5a35dc27446..7bc2fa1b09e 100644 --- a/tests/ui/type-alias-impl-trait/lazy_subtyping_of_opaques.stderr +++ b/tests/ui/type-alias-impl-trait/lazy_subtyping_of_opaques.stderr @@ -1,26 +1,31 @@ -error[E0308]: mismatched types - --> $DIR/lazy_subtyping_of_opaques.rs:10:23 +error[E0277]: expected a `FnOnce()` closure, found `()` + --> $DIR/lazy_subtyping_of_opaques.rs:11:23 | -LL | type Tait = impl FnOnce() -> (); - | ------------------- the found opaque type -... LL | Thunk::new(|cont| cont) - | ^^^^ expected `()`, found opaque type + | ^^^^ expected an `FnOnce()` closure, found `()` | - = note: expected unit type `()` - found opaque type `Tait` + = help: the trait `FnOnce()` is not implemented for `()` + = note: wrap the `()` in a closure with no arguments: `|| { /* code */ }` -error[E0308]: mismatched types - --> $DIR/lazy_subtyping_of_opaques.rs:10:5 +error[E0277]: expected a `FnOnce()` closure, found `()` + --> $DIR/lazy_subtyping_of_opaques.rs:9:23 | LL | fn reify_as_tait() -> Thunk<Tait> { - | ----------- expected `Thunk<_>` because of return type + | ^^^^^^^^^^^ expected an `FnOnce()` closure, found `()` + | + = help: the trait `FnOnce()` is not implemented for `()` + = note: wrap the `()` in a closure with no arguments: `|| { /* code */ }` + +error[E0308]: mismatched types + --> $DIR/lazy_subtyping_of_opaques.rs:11:5 + | LL | Thunk::new(|cont| cont) | ^^^^^^^^^^^^^^^^^^^^^^^ expected `Thunk<_>`, found `()` | = note: expected struct `Thunk<_>` found unit type `()` -error: aborting due to 2 previous errors +error: aborting due to 3 previous errors -For more information about this error, try `rustc --explain E0308`. +Some errors have detailed explanations: E0277, E0308. +For more information about an error, try `rustc --explain E0277`. diff --git a/tests/ui/unwind-abis/feature-gate-c_unwind.rs b/tests/ui/unwind-abis/feature-gate-c_unwind.rs deleted file mode 100644 index 28ef7d57788..00000000000 --- a/tests/ui/unwind-abis/feature-gate-c_unwind.rs +++ /dev/null @@ -1,4 +0,0 @@ -//@ ignore-test - -// After partial stabilisation, `c_unwind` only contains codegen behaviour changes -// and are tested in `src/test/codegen/unwind-abis` diff --git a/tests/crashes/123276.rs b/tests/ui/where-clauses/normalization-of-unknown-type.rs index d2246f59583..c3ff7ed125a 100644 --- a/tests/crashes/123276.rs +++ b/tests/ui/where-clauses/normalization-of-unknown-type.rs @@ -1,4 +1,6 @@ -//@ known-bug: rust-lang/rust#123276 +//! This test used to ICE: rust-lang/rust#123276 because we did +//! not taint when failing to find the `Foo` type and then tried +//! to normalize it. //@ edition:2021 async fn create_task() { @@ -19,7 +21,9 @@ struct AndThen; impl Filter for AndThen where - Foo: Filter, + Foo: Filter, //~ ERROR: cannot find type `Foo` { type Future = (); } + +fn main() {} diff --git a/tests/ui/where-clauses/normalization-of-unknown-type.stderr b/tests/ui/where-clauses/normalization-of-unknown-type.stderr new file mode 100644 index 00000000000..11b83224352 --- /dev/null +++ b/tests/ui/where-clauses/normalization-of-unknown-type.stderr @@ -0,0 +1,9 @@ +error[E0412]: cannot find type `Foo` in this scope + --> $DIR/normalization-of-unknown-type.rs:24:5 + | +LL | Foo: Filter, + | ^^^ not found in this scope + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0412`. |
