From 9a81dc97fb088c5cd088302d950000cd2565bb48 Mon Sep 17 00:00:00 2001 From: Jubilee Young Date: Sun, 15 Dec 2024 15:28:17 -0800 Subject: [PATCH 01/81] compiler: Set `target_abi = "ilp32e"` on all riscv32e targets This allows compile-time configuration based on this. In the near future we should do this across all RISCV targets, probably, but this cfg is essential for building software usable on these targets. --- .../src/spec/targets/riscv32e_unknown_none_elf.rs | 4 +++- .../src/spec/targets/riscv32em_unknown_none_elf.rs | 4 +++- .../src/spec/targets/riscv32emc_unknown_none_elf.rs | 4 +++- tests/ui/check-cfg/well-known-values.stderr | 2 +- 4 files changed, 10 insertions(+), 4 deletions(-) diff --git a/compiler/rustc_target/src/spec/targets/riscv32e_unknown_none_elf.rs b/compiler/rustc_target/src/spec/targets/riscv32e_unknown_none_elf.rs index b1f52973c107..771ffac7d804 100644 --- a/compiler/rustc_target/src/spec/targets/riscv32e_unknown_none_elf.rs +++ b/compiler/rustc_target/src/spec/targets/riscv32e_unknown_none_elf.rs @@ -1,6 +1,7 @@ use crate::spec::{Cc, LinkerFlavor, Lld, PanicStrategy, RelocModel, Target, TargetOptions}; pub(crate) fn target() -> Target { + let abi = "ilp32e"; Target { // The below `data_layout` is explicitly specified by the ilp32e ABI in LLVM. See also // `options.llvm_abiname`. @@ -16,11 +17,12 @@ pub(crate) fn target() -> Target { arch: "riscv32".into(), options: TargetOptions { + abi: abi.into(), linker_flavor: LinkerFlavor::Gnu(Cc::No, Lld::Yes), linker: Some("rust-lld".into()), cpu: "generic-rv32".into(), // The ilp32e ABI specifies the `data_layout` - llvm_abiname: "ilp32e".into(), + llvm_abiname: abi.into(), max_atomic_width: Some(32), atomic_cas: false, features: "+e,+forced-atomics".into(), diff --git a/compiler/rustc_target/src/spec/targets/riscv32em_unknown_none_elf.rs b/compiler/rustc_target/src/spec/targets/riscv32em_unknown_none_elf.rs index feeaa48778d4..3b81c278d3af 100644 --- a/compiler/rustc_target/src/spec/targets/riscv32em_unknown_none_elf.rs +++ b/compiler/rustc_target/src/spec/targets/riscv32em_unknown_none_elf.rs @@ -1,6 +1,7 @@ use crate::spec::{Cc, LinkerFlavor, Lld, PanicStrategy, RelocModel, Target, TargetOptions}; pub(crate) fn target() -> Target { + let abi = "ilp32e"; Target { // The below `data_layout` is explicitly specified by the ilp32e ABI in LLVM. See also // `options.llvm_abiname`. @@ -16,11 +17,12 @@ pub(crate) fn target() -> Target { arch: "riscv32".into(), options: TargetOptions { + abi: abi.into(), linker_flavor: LinkerFlavor::Gnu(Cc::No, Lld::Yes), linker: Some("rust-lld".into()), cpu: "generic-rv32".into(), // The ilp32e ABI specifies the `data_layout` - llvm_abiname: "ilp32e".into(), + llvm_abiname: abi.into(), max_atomic_width: Some(32), atomic_cas: false, features: "+e,+m,+forced-atomics".into(), diff --git a/compiler/rustc_target/src/spec/targets/riscv32emc_unknown_none_elf.rs b/compiler/rustc_target/src/spec/targets/riscv32emc_unknown_none_elf.rs index 45d73c132337..c18b51ad46e8 100644 --- a/compiler/rustc_target/src/spec/targets/riscv32emc_unknown_none_elf.rs +++ b/compiler/rustc_target/src/spec/targets/riscv32emc_unknown_none_elf.rs @@ -1,6 +1,7 @@ use crate::spec::{Cc, LinkerFlavor, Lld, PanicStrategy, RelocModel, Target, TargetOptions}; pub(crate) fn target() -> Target { + let abi = "ilp32e"; Target { // The below `data_layout` is explicitly specified by the ilp32e ABI in LLVM. See also // `options.llvm_abiname`. @@ -16,11 +17,12 @@ pub(crate) fn target() -> Target { arch: "riscv32".into(), options: TargetOptions { + abi: abi.into(), linker_flavor: LinkerFlavor::Gnu(Cc::No, Lld::Yes), linker: Some("rust-lld".into()), cpu: "generic-rv32".into(), // The ilp32e ABI specifies the `data_layout` - llvm_abiname: "ilp32e".into(), + llvm_abiname: abi.into(), max_atomic_width: Some(32), atomic_cas: false, features: "+e,+m,+c,+forced-atomics".into(), diff --git a/tests/ui/check-cfg/well-known-values.stderr b/tests/ui/check-cfg/well-known-values.stderr index 7c03d0570db5..702975b76e34 100644 --- a/tests/ui/check-cfg/well-known-values.stderr +++ b/tests/ui/check-cfg/well-known-values.stderr @@ -129,7 +129,7 @@ warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE` LL | target_abi = "_UNEXPECTED_VALUE", | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = note: expected values for `target_abi` are: ``, `abi64`, `abiv2`, `abiv2hf`, `eabi`, `eabihf`, `fortanix`, `ilp32`, `llvm`, `macabi`, `sim`, `softfloat`, `spe`, `uwp`, `vec-extabi`, and `x32` + = note: expected values for `target_abi` are: ``, `abi64`, `abiv2`, `abiv2hf`, `eabi`, `eabihf`, `fortanix`, `ilp32`, `ilp32e`, `llvm`, `macabi`, `sim`, `softfloat`, `spe`, `uwp`, `vec-extabi`, and `x32` = note: see for more information about checking conditional configuration warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE` From 43b7e28601b7ea0c1d77e6df5f5af97cd55531ff Mon Sep 17 00:00:00 2001 From: Antoni Boucher Date: Mon, 13 Jan 2025 10:53:58 -0500 Subject: [PATCH 02/81] Merge commit '59a81c2ca1edc88ad3ac4b27a8e03977ffb8e73a' into subtree-update_cg_gcc_2025_01_12 --- .github/workflows/ci.yml | 7 +- .github/workflows/failures.yml | 7 +- .github/workflows/gcc12.yml | 3 - .github/workflows/m68k.yml | 5 +- .github/workflows/release.yml | 10 +- .github/workflows/stdarch.yml | 5 +- Cargo.lock | 154 +++++++++- Cargo.toml | 5 +- build_system/src/test.rs | 88 ++++-- example/mini_core.rs | 8 + libgccjit.version | 2 +- ...022-core-Disable-not-compiling-tests.patch | 13 +- ...0001-core-Disable-portable-simd-test.patch | 3 +- rust-toolchain | 2 +- src/allocator.rs | 26 +- src/back/lto.rs | 37 ++- src/back/write.rs | 155 +++++++--- src/base.rs | 48 ++- src/builder.rs | 72 +++-- src/callee.rs | 137 ++++----- src/common.rs | 6 +- src/consts.rs | 3 +- src/context.rs | 1 + src/errors.rs | 4 - src/gcc_util.rs | 44 ++- src/int.rs | 4 +- src/intrinsic/llvm.rs | 2 +- src/intrinsic/mod.rs | 21 +- src/intrinsic/simd.rs | 3 +- src/lib.rs | 38 +-- tests/failing-non-lto-tests.txt | 11 - tests/failing-ui-tests.txt | 32 +- tests/failing-ui-tests12.txt | 1 - tests/hello-world/Cargo.lock | 14 + tests/hello-world/Cargo.toml | 8 + tests/hello-world/mylib/Cargo.lock | 5 + tests/hello-world/mylib/Cargo.toml | 9 + tests/hello-world/mylib/src/lib.rs | 7 + tests/hello-world/src/main.rs | 4 +- tests/lang_tests_common.rs | 24 +- tests/run/array.rs | 206 +------------ tests/run/closure.rs | 184 +---------- tests/run/condition.rs | 288 +----------------- tests/run/fun_ptr.rs | 196 +----------- tests/run/operations.rs | 4 +- tests/run/ptr_cast.rs | 196 +----------- tests/run/return-tuple.rs | 28 +- tests/run/slice.rs | 101 +----- tests/run/volatile2.rs | 113 +++++++ 49 files changed, 825 insertions(+), 1519 deletions(-) delete mode 100644 tests/failing-non-lto-tests.txt create mode 100644 tests/hello-world/Cargo.lock create mode 100644 tests/hello-world/mylib/Cargo.lock create mode 100644 tests/hello-world/mylib/Cargo.toml create mode 100644 tests/hello-world/mylib/src/lib.rs create mode 100644 tests/run/volatile2.rs diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 704d7b9c2fd6..73ec6b84a155 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -22,7 +22,6 @@ jobs: - { gcc: "gcc-13.deb" } - { gcc: "gcc-13-without-int128.deb" } commands: [ - "--mini-tests", "--std-tests", # FIXME: re-enable asm tests when GCC can emit in the right syntax. # "--asm-tests", @@ -79,6 +78,7 @@ jobs: run: | ./y.sh prepare --only-libcore ./y.sh build --sysroot + ./y.sh test --mini-tests cargo test - name: Run y.sh cargo build @@ -87,7 +87,7 @@ jobs: - name: Clean run: | - ./y.sh clean all + ./y.sh clean all - name: Prepare dependencies run: | @@ -95,9 +95,6 @@ jobs: git config --global user.name "User" ./y.sh prepare - - name: Add more failing tests because the sysroot is not compiled with LTO - run: cat tests/failing-non-lto-tests.txt >> tests/failing-ui-tests.txt - - name: Run tests run: | ./y.sh test --release --clean --build-sysroot ${{ matrix.commands }} diff --git a/.github/workflows/failures.yml b/.github/workflows/failures.yml index 2c1ed9ad4294..f33d9fcc5825 100644 --- a/.github/workflows/failures.yml +++ b/.github/workflows/failures.yml @@ -90,15 +90,12 @@ jobs: if: matrix.libgccjit_version.gcc != 'libgccjit12.so' run: ./y.sh prepare - - name: Add more failing tests because the sysroot is not compiled with LTO - run: cat tests/failing-non-lto-tests.txt >> tests/failing-ui-tests.txt - - name: Run tests # TODO: re-enable those tests for libgccjit 12. if: matrix.libgccjit_version.gcc != 'libgccjit12.so' id: tests run: | - ${{ matrix.libgccjit_version.env_extra }} ./y.sh test --release --clean --build-sysroot --test-failing-rustc ${{ matrix.libgccjit_version.extra }} | tee output_log + ${{ matrix.libgccjit_version.env_extra }} ./y.sh test --release --clean --build-sysroot --test-failing-rustc ${{ matrix.libgccjit_version.extra }} 2>&1 | tee output_log rg --text "test result" output_log >> $GITHUB_STEP_SUMMARY - name: Run failing ui pattern tests for ICE @@ -106,7 +103,7 @@ jobs: if: matrix.libgccjit_version.gcc != 'libgccjit12.so' id: ui-tests run: | - ${{ matrix.libgccjit_version.env_extra }} ./y.sh test --release --test-failing-ui-pattern-tests ${{ matrix.libgccjit_version.extra }} | tee output_log_ui + ${{ matrix.libgccjit_version.env_extra }} ./y.sh test --release --test-failing-ui-pattern-tests ${{ matrix.libgccjit_version.extra }} 2>&1 | tee output_log_ui if grep -q "the compiler unexpectedly panicked" output_log_ui; then echo "Error: 'the compiler unexpectedly panicked' found in output logs. CI Error!!" exit 1 diff --git a/.github/workflows/gcc12.yml b/.github/workflows/gcc12.yml index 7dcad21a02e1..4c2ce91e86ee 100644 --- a/.github/workflows/gcc12.yml +++ b/.github/workflows/gcc12.yml @@ -82,9 +82,6 @@ jobs: #- name: Add more failing tests for GCC 12 #run: cat tests/failing-ui-tests12.txt >> tests/failing-ui-tests.txt - #- name: Add more failing tests because the sysroot is not compiled with LTO - #run: cat tests/failing-non-lto-tests.txt >> tests/failing-ui-tests.txt - #- name: Run tests #run: | #./y.sh test --release --clean --build-sysroot ${{ matrix.commands }} --no-default-features diff --git a/.github/workflows/m68k.yml b/.github/workflows/m68k.yml index 1c864e04413f..07bb372b3606 100644 --- a/.github/workflows/m68k.yml +++ b/.github/workflows/m68k.yml @@ -23,7 +23,6 @@ jobs: fail-fast: false matrix: commands: [ - "--mini-tests", "--std-tests", # TODO(antoyo): fix those on m68k. #"--test-libcore", @@ -93,6 +92,7 @@ jobs: run: | ./y.sh prepare --only-libcore --cross ./y.sh build --sysroot --features compiler_builtins/no-f16-f128 --target-triple m68k-unknown-linux-gnu + ./y.sh test --mini-tests CG_GCC_TEST_TARGET=m68k-unknown-linux-gnu cargo test ./y.sh clean all @@ -102,9 +102,6 @@ jobs: git config --global user.name "User" ./y.sh prepare --cross - - name: Add more failing tests because the sysroot is not compiled with LTO - run: cat tests/failing-non-lto-tests.txt >> tests/failing-ui-tests.txt - - name: Run tests run: | ./y.sh test --release --clean --build-sysroot --sysroot-features compiler_builtins/no-f16-f128 ${{ matrix.commands }} diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index d5c06a836db9..60e0943c87da 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -13,7 +13,7 @@ env: jobs: build: - runs-on: ubuntu-latest + runs-on: ubuntu-22.04 strategy: fail-fast: false @@ -54,6 +54,7 @@ jobs: run: | ./y.sh prepare --only-libcore EMBED_LTO_BITCODE=1 ./y.sh build --sysroot --release --release-sysroot + ./y.sh test --mini-tests cargo test ./y.sh clean all @@ -70,4 +71,9 @@ jobs: run: | # FIXME(antoyo): we cannot enable LTO for stdarch tests currently because of some failing LTO tests using proc-macros. echo -n 'lto = "fat"' >> build_system/build_sysroot/Cargo.toml - EMBED_LTO_BITCODE=1 ./y.sh test --release --clean --release-sysroot --build-sysroot ${{ matrix.commands }} + EMBED_LTO_BITCODE=1 ./y.sh test --release --clean --release-sysroot --build-sysroot --keep-lto-tests ${{ matrix.commands }} + + - name: Run y.sh cargo build + run: | + EMBED_LTO_BITCODE=1 CHANNEL="release" ./y.sh cargo build --release --manifest-path tests/hello-world/Cargo.toml + # TODO: grep the asm output for "call my_func" and fail if it is found. diff --git a/.github/workflows/stdarch.yml b/.github/workflows/stdarch.yml index d8818eefa96d..d5ae6144496f 100644 --- a/.github/workflows/stdarch.yml +++ b/.github/workflows/stdarch.yml @@ -73,10 +73,6 @@ jobs: echo "LD_LIBRARY_PATH="$(./y.sh info | grep -v Using) >> $GITHUB_ENV echo "LIBRARY_PATH="$(./y.sh info | grep -v Using) >> $GITHUB_ENV - - name: Build (part 2) - run: | - cargo test - - name: Clean if: ${{ !matrix.cargo_runner }} run: | @@ -92,6 +88,7 @@ jobs: if: ${{ !matrix.cargo_runner }} run: | ./y.sh test --release --clean --release-sysroot --build-sysroot --mini-tests --std-tests --test-libcore + cargo test - name: Run stdarch tests if: ${{ !matrix.cargo_runner }} diff --git a/Cargo.lock b/Cargo.lock index 6b06e7d7f278..636e75b94a3f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1,6 +1,6 @@ # This file is automatically @generated by Cargo. # It is not intended for manual editing. -version = 3 +version = 4 [[package]] name = "aho-corasick" @@ -11,12 +11,40 @@ dependencies = [ "memchr", ] +[[package]] +name = "bitflags" +version = "2.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" + [[package]] name = "boml" version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "85fdb93f04c73bff54305fa437ffea5449c41edcaadfe882f35836206b166ac5" +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "errno" +version = "0.3.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "33d852cb9b869c2a9b3df2f71a3074817f01e1844f839a144f5fcef059a4eb5d" +dependencies = [ + "libc", + "windows-sys", +] + +[[package]] +name = "fastrand" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be" + [[package]] name = "fm" version = "0.2.2" @@ -28,18 +56,18 @@ dependencies = [ [[package]] name = "gccjit" -version = "2.2.0" +version = "2.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4bb376e98c82d9284c3a17fc1d6bf9bc921055418950238d7a553c27a7e1f6ab" +checksum = "72fd91f4adbf02b53cfc73c97bc33c5f253009043f30c56a5ec08dd5c8094dc8" dependencies = [ "gccjit_sys", ] [[package]] name = "gccjit_sys" -version = "0.3.0" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93b4b1be553b5df790bf25ca2a1d6add81727dc29f8d5c8742468ed306d621d1" +checksum = "0fb7b8f48a75e2cfe78c3d9a980b32771c34ffd12d196021ab3f98c49fbd2f0d" dependencies = [ "libc", ] @@ -77,9 +105,15 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.150" +version = "0.2.168" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89d92a4743f9a61002fae18374ed11e7973f530cb3a3255fb354818118b2203c" +checksum = "5aaeb2981e0606ca11d79718f8bb01164f1d6ed75080182d3abf017e6d244b6d" + +[[package]] +name = "linux-raw-sys" +version = "0.4.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89" [[package]] name = "memchr" @@ -97,6 +131,12 @@ dependencies = [ "libc", ] +[[package]] +name = "once_cell" +version = "1.20.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1261fe7e33c73b354eab43b1273a57c8f967d0391e80353e51f764ac02cf6775" + [[package]] name = "regex" version = "1.8.4" @@ -121,6 +161,20 @@ dependencies = [ "boml", "gccjit", "lang_tester", + "tempfile", +] + +[[package]] +name = "rustix" +version = "0.38.42" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f93dc38ecbab2eb790ff964bb77fa94faf256fd3e73285fd7ba0903b76bedb85" +dependencies = [ + "bitflags", + "errno", + "libc", + "linux-raw-sys", + "windows-sys", ] [[package]] @@ -132,6 +186,19 @@ dependencies = [ "winapi-util", ] +[[package]] +name = "tempfile" +version = "3.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "28cce251fcbc87fac86a866eeb0d6c2d536fc16d06f184bb61aeae11aa4cee0c" +dependencies = [ + "cfg-if", + "fastrand", + "once_cell", + "rustix", + "windows-sys", +] + [[package]] name = "termcolor" version = "1.2.0" @@ -205,3 +272,76 @@ name = "winapi-x86_64-pc-windows-gnu" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + +[[package]] +name = "windows-sys" +version = "0.59.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" +dependencies = [ + "windows-targets", +] + +[[package]] +name = "windows-targets" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" +dependencies = [ + "windows_aarch64_gnullvm", + "windows_aarch64_msvc", + "windows_i686_gnu", + "windows_i686_gnullvm", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" + +[[package]] +name = "windows_i686_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" + +[[package]] +name = "windows_i686_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" diff --git a/Cargo.toml b/Cargo.toml index 4828b7ddb168..63d37358561e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -22,15 +22,16 @@ master = ["gccjit/master"] default = ["master"] [dependencies] -gccjit = "2.2" +gccjit = "2.4" #gccjit = { git = "https://github.com/rust-lang/gccjit.rs" } # Local copy. #gccjit = { path = "../gccjit.rs" } [dev-dependencies] -lang_tester = "0.8.0" boml = "0.3.1" +lang_tester = "0.8.0" +tempfile = "3.7.1" [profile.dev] # By compiling dependencies with optimizations, performing tests gets much faster. diff --git a/build_system/src/test.rs b/build_system/src/test.rs index c69e240c01de..7cc7336612c7 100644 --- a/build_system/src/test.rs +++ b/build_system/src/test.rs @@ -93,6 +93,7 @@ struct TestArg { sysroot_panic_abort: bool, config_info: ConfigInfo, sysroot_features: Vec, + keep_lto_tests: bool, } impl TestArg { @@ -128,6 +129,9 @@ impl TestArg { "--sysroot-panic-abort" => { test_arg.sysroot_panic_abort = true; } + "--keep-lto-tests" => { + test_arg.keep_lto_tests = true; + } "--sysroot-features" => match args.next() { Some(feature) if !feature.is_empty() => { test_arg.sysroot_features.push(feature); @@ -194,7 +198,7 @@ fn build_if_no_backend(env: &Env, args: &TestArg) -> Result<(), String> { } fn clean(_env: &Env, args: &TestArg) -> Result<(), String> { - let _ = std::fs::remove_dir_all(&args.config_info.cargo_target_dir); + let _ = remove_dir_all(&args.config_info.cargo_target_dir); let path = Path::new(&args.config_info.cargo_target_dir).join("gccjit"); create_dir(&path) } @@ -641,7 +645,7 @@ fn test_projects(env: &Env, args: &TestArg) -> Result<(), String> { //failing test is fixed upstream. //"https://github.com/marshallpierce/rust-base64", // FIXME: one test is OOM-killed. // TODO: ignore the base64 test that is OOM-killed. - "https://github.com/time-rs/time", + //"https://github.com/time-rs/time", // FIXME: one test fails (https://github.com/time-rs/time/issues/719). "https://github.com/rust-lang/log", "https://github.com/bitflags/bitflags", //"https://github.com/serde-rs/serde", // FIXME: one test fails. @@ -835,8 +839,7 @@ fn valid_ui_error_pattern_test(file: &str) -> bool { .any(|to_ignore| file.ends_with(to_ignore)) } -#[rustfmt::skip] -fn contains_ui_error_patterns(file_path: &Path) -> Result { +fn contains_ui_error_patterns(file_path: &Path, keep_lto_tests: bool) -> Result { // Tests generating errors. let file = File::open(file_path) .map_err(|error| format!("Failed to read `{}`: {:?}", file_path.display(), error))?; @@ -849,22 +852,38 @@ fn contains_ui_error_patterns(file_path: &Path) -> Result { "//@ error-pattern:", "//@ build-fail", "//@ run-fail", + "//@ known-bug", "-Cllvm-args", "//~", "thread", ] - .iter() - .any(|check| line.contains(check)) + .iter() + .any(|check| line.contains(check)) { return Ok(true); } + + if !keep_lto_tests + && (line.contains("-Clto") + || line.contains("-C lto") + || line.contains("compile-flags: -Clinker-plugin-lto")) + && !line.contains("-Clto=thin") + { + return Ok(true); + } + if line.contains("//[") && line.contains("]~") { return Ok(true); } } - if file_path.display().to_string().contains("ambiguous-4-extern.rs") { + let file_path = file_path.display().to_string(); + if file_path.contains("ambiguous-4-extern.rs") { eprintln!("nothing found for {file_path:?}"); } + // The files in this directory contain errors. + if file_path.contains("/error-emitter/") { + return Ok(true); + } Ok(false) } @@ -903,7 +922,7 @@ where rust_path.join("tests/ui"), &mut |_dir| Ok(()), &mut |file_path| { - if contains_ui_error_patterns(file_path)? { + if contains_ui_error_patterns(file_path, args.keep_lto_tests)? { Ok(()) } else { remove_file(file_path).map_err(|e| e.to_string()) @@ -928,7 +947,7 @@ where .iter() .any(|name| *name == dir_name) { - std::fs::remove_dir_all(dir).map_err(|error| { + remove_dir_all(dir).map_err(|error| { format!("Failed to remove folder `{}`: {:?}", dir.display(), error) })?; } @@ -940,27 +959,42 @@ where // These two functions are used to remove files that are known to not be working currently // with the GCC backend to reduce noise. - fn dir_handling(dir: &Path) -> Result<(), String> { - if dir.file_name().map(|name| name == "auxiliary").unwrap_or(true) { - return Ok(()); - } + fn dir_handling(keep_lto_tests: bool) -> impl Fn(&Path) -> Result<(), String> { + move |dir| { + if dir.file_name().map(|name| name == "auxiliary").unwrap_or(true) { + return Ok(()); + } - walk_dir(dir, &mut dir_handling, &mut file_handling, false) - } - fn file_handling(file_path: &Path) -> Result<(), String> { - if !file_path.extension().map(|extension| extension == "rs").unwrap_or(false) { - return Ok(()); + walk_dir( + dir, + &mut dir_handling(keep_lto_tests), + &mut file_handling(keep_lto_tests), + false, + ) } - let path_str = file_path.display().to_string().replace("\\", "/"); - if valid_ui_error_pattern_test(&path_str) { - return Ok(()); - } else if contains_ui_error_patterns(file_path)? { - return remove_file(&file_path); - } - Ok(()) } - walk_dir(rust_path.join("tests/ui"), &mut dir_handling, &mut file_handling, false)?; + fn file_handling(keep_lto_tests: bool) -> impl Fn(&Path) -> Result<(), String> { + move |file_path| { + if !file_path.extension().map(|extension| extension == "rs").unwrap_or(false) { + return Ok(()); + } + let path_str = file_path.display().to_string().replace("\\", "/"); + if valid_ui_error_pattern_test(&path_str) { + return Ok(()); + } else if contains_ui_error_patterns(file_path, keep_lto_tests)? { + return remove_file(&file_path); + } + Ok(()) + } + } + + walk_dir( + rust_path.join("tests/ui"), + &mut dir_handling(args.keep_lto_tests), + &mut file_handling(args.keep_lto_tests), + false, + )?; } let nb_parts = args.nb_parts.unwrap_or(0); if nb_parts > 0 { @@ -1173,7 +1207,7 @@ fn remove_files_callback<'a>( files.split('\n').map(|line| line.trim()).filter(|line| !line.is_empty()) { let path = rust_path.join(file); - if let Err(e) = std::fs::remove_dir_all(&path) { + if let Err(e) = remove_dir_all(&path) { println!("Failed to remove directory `{}`: {}", path.display(), e); } } diff --git a/example/mini_core.rs b/example/mini_core.rs index cdd151613df8..bd7a4612a92c 100644 --- a/example/mini_core.rs +++ b/example/mini_core.rs @@ -170,6 +170,14 @@ impl Add for usize { } } +impl Add for isize { + type Output = Self; + + fn add(self, rhs: Self) -> Self { + self + rhs + } +} + #[lang = "sub"] pub trait Sub { type Output; diff --git a/libgccjit.version b/libgccjit.version index b9bbbd324c3b..ff58accec1d4 100644 --- a/libgccjit.version +++ b/libgccjit.version @@ -1 +1 @@ -e744a9459d33864067214741daf5c5bc2a7b88c6 +45648c2edd4ecd862d9f08196d3d6c6ccba79f07 diff --git a/patches/0022-core-Disable-not-compiling-tests.patch b/patches/0022-core-Disable-not-compiling-tests.patch index b2ab05691ecb..70e3e2ba7fee 100644 --- a/patches/0022-core-Disable-not-compiling-tests.patch +++ b/patches/0022-core-Disable-not-compiling-tests.patch @@ -1,7 +1,7 @@ -From 18793c6109890493ceb3ff36549849a36e3d8022 Mon Sep 17 00:00:00 2001 +From af0e237f056fa838c77463381a19b0dc993c0a35 Mon Sep 17 00:00:00 2001 From: None Date: Sun, 1 Sep 2024 11:42:17 -0400 -Subject: [PATCH] [core] Disable not compiling tests +Subject: [PATCH] Disable not compiling tests --- library/core/tests/Cargo.toml | 14 ++++++++++++++ @@ -30,14 +30,15 @@ index 0000000..ca326ac +rand = { version = "0.8.5", default-features = false } +rand_xorshift = { version = "0.3.0", default-features = false } diff --git a/library/core/tests/lib.rs b/library/core/tests/lib.rs -index 1e336bf..5800ebb 100644 +index a4a7946..ecfe43f 100644 --- a/library/core/tests/lib.rs +++ b/library/core/tests/lib.rs @@ -1,4 +1,5 @@ // tidy-alphabetical-start +#![cfg(test)] - #![cfg_attr(bootstrap, feature(offset_of_nested))] #![cfg_attr(target_has_atomic = "128", feature(integer_atomics))] #![cfg_attr(test, feature(cfg_match))] --- -2.46.0 + #![feature(alloc_layout_extra)] +-- +2.47.1 + diff --git a/patches/libgccjit12/0001-core-Disable-portable-simd-test.patch b/patches/libgccjit12/0001-core-Disable-portable-simd-test.patch index 01461987ffb1..9ef5e0e4f467 100644 --- a/patches/libgccjit12/0001-core-Disable-portable-simd-test.patch +++ b/patches/libgccjit12/0001-core-Disable-portable-simd-test.patch @@ -27,5 +27,4 @@ index b71786c..cf484d5 100644 mod slice; mod str; mod str_lossy; --- -2.45.2 +-- 2.45.2 diff --git a/rust-toolchain b/rust-toolchain index dca3b0c22e4e..940b3de9f745 100644 --- a/rust-toolchain +++ b/rust-toolchain @@ -1,3 +1,3 @@ [toolchain] -channel = "nightly-2024-08-11" +channel = "nightly-2025-01-12" components = ["rust-src", "rustc-dev", "llvm-tools-preview"] diff --git a/src/allocator.rs b/src/allocator.rs index f13a75648aea..416f3231a13c 100644 --- a/src/allocator.rs +++ b/src/allocator.rs @@ -1,6 +1,6 @@ -#[cfg(feature = "master")] -use gccjit::FnAttribute; use gccjit::{Context, FunctionType, GlobalKind, ToRValue, Type}; +#[cfg(feature = "master")] +use gccjit::{FnAttribute, VarAttribute}; use rustc_ast::expand::allocator::{ ALLOCATOR_METHODS, AllocatorKind, AllocatorTy, NO_ALLOC_SHIM_IS_UNSTABLE, alloc_error_handler_name, default_fn_name, global_fn_name, @@ -10,6 +10,8 @@ use rustc_middle::ty::TyCtxt; use rustc_session::config::OomStrategy; use crate::GccContext; +#[cfg(feature = "master")] +use crate::base::symbol_visibility_to_gcc; pub(crate) unsafe fn codegen( tcx: TyCtxt<'_>, @@ -70,12 +72,20 @@ pub(crate) unsafe fn codegen( let name = OomStrategy::SYMBOL.to_string(); let global = context.new_global(None, GlobalKind::Exported, i8, name); + #[cfg(feature = "master")] + global.add_attribute(VarAttribute::Visibility(symbol_visibility_to_gcc( + tcx.sess.default_visibility(), + ))); let value = tcx.sess.opts.unstable_opts.oom.should_panic(); let value = context.new_rvalue_from_int(i8, value as i32); global.global_set_initializer_rvalue(value); let name = NO_ALLOC_SHIM_IS_UNSTABLE.to_string(); let global = context.new_global(None, GlobalKind::Exported, i8, name); + #[cfg(feature = "master")] + global.add_attribute(VarAttribute::Visibility(symbol_visibility_to_gcc( + tcx.sess.default_visibility(), + ))); let value = context.new_rvalue_from_int(i8, 0); global.global_set_initializer_rvalue(value); } @@ -105,15 +115,9 @@ fn create_wrapper_function( ); #[cfg(feature = "master")] - match tcx.sess.default_visibility() { - rustc_target::spec::SymbolVisibility::Hidden => { - func.add_attribute(FnAttribute::Visibility(gccjit::Visibility::Hidden)) - } - rustc_target::spec::SymbolVisibility::Protected => { - func.add_attribute(FnAttribute::Visibility(gccjit::Visibility::Protected)) - } - rustc_target::spec::SymbolVisibility::Interposable => {} - } + func.add_attribute(FnAttribute::Visibility(symbol_visibility_to_gcc( + tcx.sess.default_visibility(), + ))); if tcx.sess.must_emit_unwind_tables() { // TODO(antoyo): emit unwind tables. diff --git a/src/back/lto.rs b/src/back/lto.rs index f7173d4d2ffc..e419bd180990 100644 --- a/src/back/lto.rs +++ b/src/back/lto.rs @@ -35,16 +35,13 @@ use rustc_middle::bug; use rustc_middle::dep_graph::WorkProduct; use rustc_middle::middle::exported_symbols::{SymbolExportInfo, SymbolExportLevel}; use rustc_session::config::{CrateType, Lto}; +use rustc_target::spec::RelocModel; use tempfile::{TempDir, tempdir}; use crate::back::write::save_temp_bitcode; use crate::errors::{DynamicLinkingWithLTO, LtoBitcodeFromRlib, LtoDisallowed, LtoDylib}; use crate::{GccCodegenBackend, GccContext, SyncContext, to_gcc_opt_level}; -/// We keep track of the computed LTO cache keys from the previous -/// session to determine which CGUs we can reuse. -//pub const THIN_LTO_KEYS_INCR_COMP_FILE_NAME: &str = "thin-lto-past-keys.bin"; - pub fn crate_type_allows_lto(crate_type: CrateType) -> bool { match crate_type { CrateType::Executable | CrateType::Dylib | CrateType::Staticlib | CrateType::Cdylib => true, @@ -54,7 +51,7 @@ pub fn crate_type_allows_lto(crate_type: CrateType) -> bool { struct LtoData { // TODO(antoyo): use symbols_below_threshold. - //symbols_below_threshold: Vec, + //symbols_below_threshold: Vec, upstream_modules: Vec<(SerializedModule, CString)>, tmp_path: TempDir, } @@ -83,7 +80,7 @@ fn prepare_lto( let symbol_filter = &|&(ref name, info): &(String, SymbolExportInfo)| { if info.level.is_below_threshold(export_threshold) || info.used { - Some(CString::new(name.as_str()).unwrap()) + Some(name.clone()) } else { None } @@ -91,7 +88,7 @@ fn prepare_lto( let exported_symbols = cgcx.exported_symbols.as_ref().expect("needs exported symbols for LTO"); let mut symbols_below_threshold = { let _timer = cgcx.prof.generic_activity("GCC_lto_generate_symbols_below_threshold"); - exported_symbols[&LOCAL_CRATE].iter().filter_map(symbol_filter).collect::>() + exported_symbols[&LOCAL_CRATE].iter().filter_map(symbol_filter).collect::>() }; info!("{} symbols to preserve in this crate", symbols_below_threshold.len()); @@ -159,11 +156,7 @@ fn prepare_lto( } } - Ok(LtoData { - //symbols_below_threshold, - upstream_modules, - tmp_path, - }) + Ok(LtoData { upstream_modules, tmp_path }) } fn save_as_file(obj: &[u8], path: &Path) -> Result<(), LtoBitcodeFromRlib> { @@ -191,7 +184,7 @@ pub(crate) fn run_fat( cached_modules, lto_data.upstream_modules, lto_data.tmp_path, - //&symbols_below_threshold, + //<o_data.symbols_below_threshold, ) } @@ -202,7 +195,7 @@ fn fat_lto( cached_modules: Vec<(SerializedModule, WorkProduct)>, mut serialized_modules: Vec<(SerializedModule, CString)>, tmp_path: TempDir, - //symbols_below_threshold: &[*const libc::c_char], + //symbols_below_threshold: &[String], ) -> Result, FatalError> { let _timer = cgcx.prof.generic_activity("GCC_fat_lto_build_monolithic_module"); info!("going for a fat lto"); @@ -327,6 +320,7 @@ fn fat_lto( ptr as *const *const libc::c_char, symbols_below_threshold.len() as libc::size_t, );*/ + save_temp_bitcode(cgcx, &module, "lto.after-restriction"); //} } @@ -363,8 +357,6 @@ pub(crate) fn run_thin( let dcx = cgcx.create_dcx(); let dcx = dcx.handle(); let lto_data = prepare_lto(cgcx, dcx)?; - /*let symbols_below_threshold = - symbols_below_threshold.iter().map(|c| c.as_ptr()).collect::>();*/ if cgcx.opts.cg.linker_plugin_lto.enabled() { unreachable!( "We should never reach this case if the LTO step \ @@ -377,7 +369,8 @@ pub(crate) fn run_thin( modules, lto_data.upstream_modules, lto_data.tmp_path, - cached_modules, /*, &symbols_below_threshold*/ + cached_modules, + //<o_data.symbols_below_threshold, ) } @@ -428,7 +421,7 @@ fn thin_lto( serialized_modules: Vec<(SerializedModule, CString)>, tmp_path: TempDir, cached_modules: Vec<(SerializedModule, WorkProduct)>, - //symbols_below_threshold: &[*const libc::c_char], + //_symbols_below_threshold: &[String], ) -> Result<(Vec>, Vec), FatalError> { let _timer = cgcx.prof.generic_activity("LLVM_thin_lto_global_analysis"); info!("going for that thin, thin LTO"); @@ -640,7 +633,13 @@ pub unsafe fn optimize_thin_module( } }; let module = ModuleCodegen { - module_llvm: GccContext { context, should_combine_object_files, temp_dir: None }, + module_llvm: GccContext { + context, + should_combine_object_files, + // TODO(antoyo): use the correct relocation model here. + relocation_model: RelocModel::Pic, + temp_dir: None, + }, name: thin_module.name().to_string(), kind: ModuleKind::Regular, }; diff --git a/src/back/write.rs b/src/back/write.rs index 802968979c72..51c5ba73e32b 100644 --- a/src/back/write.rs +++ b/src/back/write.rs @@ -1,6 +1,6 @@ use std::{env, fs}; -use gccjit::OutputKind; +use gccjit::{Context, OutputKind}; use rustc_codegen_ssa::back::link::ensure_removed; use rustc_codegen_ssa::back::write::{BitcodeSection, CodegenContext, EmitObj, ModuleConfig}; use rustc_codegen_ssa::{CompiledModule, ModuleCodegen}; @@ -10,6 +10,7 @@ use rustc_session::config::OutputType; use rustc_span::fatal_error::FatalError; use rustc_target::spec::SplitDebuginfo; +use crate::base::add_pic_option; use crate::errors::CopyBitcode; use crate::{GccCodegenBackend, GccContext}; @@ -31,51 +32,87 @@ pub(crate) unsafe fn codegen( // NOTE: Only generate object files with GIMPLE when this environment variable is set for // now because this requires a particular setup (same gcc/lto1/lto-wrapper commit as libgccjit). - // TODO: remove this environment variable. + // TODO(antoyo): remove this environment variable. let fat_lto = env::var("EMBED_LTO_BITCODE").as_deref() == Ok("1"); let bc_out = cgcx.output_filenames.temp_path(OutputType::Bitcode, module_name); let obj_out = cgcx.output_filenames.temp_path(OutputType::Object, module_name); - if config.bitcode_needed() && fat_lto { - let _timer = cgcx - .prof - .generic_activity_with_arg("GCC_module_codegen_make_bitcode", &*module.name); - - // TODO(antoyo) - /*if let Some(bitcode_filename) = bc_out.file_name() { - cgcx.prof.artifact_size( - "llvm_bitcode", - bitcode_filename.to_string_lossy(), - data.len() as u64, - ); - }*/ - - if config.emit_bc || config.emit_obj == EmitObj::Bitcode { + if config.bitcode_needed() { + if fat_lto { let _timer = cgcx .prof - .generic_activity_with_arg("GCC_module_codegen_emit_bitcode", &*module.name); - context.add_command_line_option("-flto=auto"); - context.add_command_line_option("-flto-partition=one"); - // TODO: remove since we don't want fat objects when it is for Bitcode only. - context.add_command_line_option("-ffat-lto-objects"); - context - .compile_to_file(OutputKind::ObjectFile, bc_out.to_str().expect("path to str")); - } + .generic_activity_with_arg("GCC_module_codegen_make_bitcode", &*module.name); - if config.emit_obj == EmitObj::ObjectCode(BitcodeSection::Full) { - let _timer = cgcx - .prof - .generic_activity_with_arg("GCC_module_codegen_embed_bitcode", &*module.name); - // TODO(antoyo): maybe we should call embed_bitcode to have the proper iOS fixes? - //embed_bitcode(cgcx, llcx, llmod, &config.bc_cmdline, data); + // TODO(antoyo) + /*if let Some(bitcode_filename) = bc_out.file_name() { + cgcx.prof.artifact_size( + "llvm_bitcode", + bitcode_filename.to_string_lossy(), + data.len() as u64, + ); + }*/ - context.add_command_line_option("-flto=auto"); - context.add_command_line_option("-flto-partition=one"); - context.add_command_line_option("-ffat-lto-objects"); - // TODO(antoyo): Send -plugin/usr/lib/gcc/x86_64-pc-linux-gnu/11.1.0/liblto_plugin.so to linker (this should be done when specifying the appropriate rustc cli argument). - context - .compile_to_file(OutputKind::ObjectFile, bc_out.to_str().expect("path to str")); + if config.emit_bc || config.emit_obj == EmitObj::Bitcode { + let _timer = cgcx.prof.generic_activity_with_arg( + "GCC_module_codegen_emit_bitcode", + &*module.name, + ); + context.add_command_line_option("-flto=auto"); + context.add_command_line_option("-flto-partition=one"); + // TODO(antoyo): remove since we don't want fat objects when it is for Bitcode only. + context.add_command_line_option("-ffat-lto-objects"); + context.compile_to_file( + OutputKind::ObjectFile, + bc_out.to_str().expect("path to str"), + ); + } + + if config.emit_obj == EmitObj::ObjectCode(BitcodeSection::Full) { + let _timer = cgcx.prof.generic_activity_with_arg( + "GCC_module_codegen_embed_bitcode", + &*module.name, + ); + // TODO(antoyo): maybe we should call embed_bitcode to have the proper iOS fixes? + //embed_bitcode(cgcx, llcx, llmod, &config.bc_cmdline, data); + + context.add_command_line_option("-flto=auto"); + context.add_command_line_option("-flto-partition=one"); + context.add_command_line_option("-ffat-lto-objects"); + // TODO(antoyo): Send -plugin/usr/lib/gcc/x86_64-pc-linux-gnu/11.1.0/liblto_plugin.so to linker (this should be done when specifying the appropriate rustc cli argument). + context.compile_to_file( + OutputKind::ObjectFile, + bc_out.to_str().expect("path to str"), + ); + } + } else { + if config.emit_bc || config.emit_obj == EmitObj::Bitcode { + let _timer = cgcx.prof.generic_activity_with_arg( + "GCC_module_codegen_emit_bitcode", + &*module.name, + ); + context.compile_to_file( + OutputKind::ObjectFile, + bc_out.to_str().expect("path to str"), + ); + } + + if config.emit_obj == EmitObj::ObjectCode(BitcodeSection::Full) { + // TODO(antoyo): we might want to emit to emit an error here, saying to set the + // environment variable EMBED_LTO_BITCODE. + let _timer = cgcx.prof.generic_activity_with_arg( + "GCC_module_codegen_embed_bitcode", + &*module.name, + ); + // TODO(antoyo): maybe we should call embed_bitcode to have the proper iOS fixes? + //embed_bitcode(cgcx, llcx, llmod, &config.bc_cmdline, data); + + // TODO(antoyo): Send -plugin/usr/lib/gcc/x86_64-pc-linux-gnu/11.1.0/liblto_plugin.so to linker (this should be done when specifying the appropriate rustc cli argument). + context.compile_to_file( + OutputKind::ObjectFile, + bc_out.to_str().expect("path to str"), + ); + } } } @@ -123,6 +160,8 @@ pub(crate) unsafe fn codegen( // NOTE: without -fuse-linker-plugin, we get the following error: // lto1: internal compiler error: decompressed stream: Destination buffer is too small + // TODO(antoyo): since we do not do LTO when the linker is invoked anymore, perhaps + // the following flag is not necessary anymore. context.add_driver_option("-fuse-linker-plugin"); } @@ -131,11 +170,43 @@ pub(crate) unsafe fn codegen( // /usr/bin/ld: cannot find -lgcc_s: No such file or directory context.add_driver_option("-nostdlib"); - // NOTE: this doesn't actually generate an executable. With the above flags, it combines the .o files together in another .o. - context.compile_to_file( - OutputKind::Executable, - obj_out.to_str().expect("path to str"), - ); + let path = obj_out.to_str().expect("path to str"); + + if fat_lto { + let lto_path = format!("{}.lto", path); + // FIXME(antoyo): The LTO frontend generates the following warning: + // ../build_sysroot/sysroot_src/library/core/src/num/dec2flt/lemire.rs:150:15: warning: type of ‘_ZN4core3num7dec2flt5table17POWER_OF_FIVE_12817ha449a68fb31379e4E’ does not match original declaration [-Wlto-type-mismatch] + // 150 | let (lo5, hi5) = POWER_OF_FIVE_128[index]; + // | ^ + // lto1: note: ‘_ZN4core3num7dec2flt5table17POWER_OF_FIVE_12817ha449a68fb31379e4E’ was previously declared here + // + // This option is to mute it to make the UI tests pass with LTO enabled. + context.add_driver_option("-Wno-lto-type-mismatch"); + // NOTE: this doesn't actually generate an executable. With the above + // flags, it combines the .o files together in another .o. + context.compile_to_file(OutputKind::Executable, <o_path); + + let context = Context::default(); + if cgcx.target_arch == "x86" || cgcx.target_arch == "x86_64" { + // NOTE: it seems we need to use add_driver_option instead of + // add_command_line_option here because we use the LTO frontend via gcc. + context.add_driver_option("-masm=intel"); + } + + // NOTE: these two options are needed to invoke LTO to produce an object file. + // We need to initiate a second compilation because the arguments "-x lto" + // needs to be at the very beginning. + context.add_driver_option("-x"); + context.add_driver_option("lto"); + add_pic_option(&context, module.module_llvm.relocation_model); + context.add_driver_option(lto_path); + + context.compile_to_file(OutputKind::ObjectFile, path); + } else { + // NOTE: this doesn't actually generate an executable. With the above + // flags, it combines the .o files together in another .o. + context.compile_to_file(OutputKind::Executable, path); + } } else { context.compile_to_file( OutputKind::ObjectFile, diff --git a/src/base.rs b/src/base.rs index 18aa32754e1d..c9701fb9885c 100644 --- a/src/base.rs +++ b/src/base.rs @@ -3,7 +3,7 @@ use std::env; use std::sync::Arc; use std::time::Instant; -use gccjit::{CType, FunctionType, GlobalKind}; +use gccjit::{CType, Context, FunctionType, GlobalKind}; use rustc_codegen_ssa::base::maybe_create_entry_wrapper; use rustc_codegen_ssa::mono_item::MonoItemExt; use rustc_codegen_ssa::traits::DebugInfoCodegenMethods; @@ -15,21 +15,32 @@ use rustc_middle::mir::mono::Visibility; use rustc_middle::ty::TyCtxt; use rustc_session::config::DebugInfo; use rustc_span::Symbol; -use rustc_target::spec::PanicStrategy; +#[cfg(feature = "master")] +use rustc_target::spec::SymbolVisibility; +use rustc_target::spec::{PanicStrategy, RelocModel}; use crate::builder::Builder; use crate::context::CodegenCx; use crate::{GccContext, LockedTargetInfo, SyncContext, gcc_util, new_context}; #[cfg(feature = "master")] -pub fn visibility_to_gcc(linkage: Visibility) -> gccjit::Visibility { - match linkage { +pub fn visibility_to_gcc(visibility: Visibility) -> gccjit::Visibility { + match visibility { Visibility::Default => gccjit::Visibility::Default, Visibility::Hidden => gccjit::Visibility::Hidden, Visibility::Protected => gccjit::Visibility::Protected, } } +#[cfg(feature = "master")] +pub fn symbol_visibility_to_gcc(visibility: SymbolVisibility) -> gccjit::Visibility { + match visibility { + SymbolVisibility::Hidden => gccjit::Visibility::Hidden, + SymbolVisibility::Protected => gccjit::Visibility::Protected, + SymbolVisibility::Interposable => gccjit::Visibility::Default, + } +} + pub fn global_linkage_to_gcc(linkage: Linkage) -> GlobalKind { match linkage { Linkage::External => GlobalKind::Imported, @@ -140,9 +151,7 @@ pub fn compile_codegen_unit( }); } - if tcx.sess.relocation_model() == rustc_target::spec::RelocModel::Static { - context.add_command_line_option("-fno-pie"); - } + add_pic_option(&context, tcx.sess.relocation_model()); let target_cpu = gcc_util::target_cpu(tcx.sess); if target_cpu != "generic" { @@ -199,12 +208,13 @@ pub fn compile_codegen_unit( let f32_type_supported = target_info.supports_target_dependent_type(CType::Float32); let f64_type_supported = target_info.supports_target_dependent_type(CType::Float64); let f128_type_supported = target_info.supports_target_dependent_type(CType::Float128); + let u128_type_supported = target_info.supports_target_dependent_type(CType::UInt128t); // TODO: improve this to avoid passing that many arguments. let cx = CodegenCx::new( &context, cgu, tcx, - target_info.supports_128bit_int(), + u128_type_supported, f16_type_supported, f32_type_supported, f64_type_supported, @@ -235,6 +245,7 @@ pub fn compile_codegen_unit( name: cgu_name.to_string(), module_llvm: GccContext { context: Arc::new(SyncContext::new(context)), + relocation_model: tcx.sess.relocation_model(), should_combine_object_files: false, temp_dir: None, }, @@ -244,3 +255,24 @@ pub fn compile_codegen_unit( (module, cost) } + +pub fn add_pic_option<'gcc>(context: &Context<'gcc>, relocation_model: RelocModel) { + match relocation_model { + rustc_target::spec::RelocModel::Static => { + context.add_command_line_option("-fno-pie"); + context.add_driver_option("-fno-pie"); + } + rustc_target::spec::RelocModel::Pic => { + context.add_command_line_option("-fPIC"); + // NOTE: we use both add_command_line_option and add_driver_option because the usage in + // this module (compile_codegen_unit) requires add_command_line_option while the usage + // in the back::write module (codegen) requires add_driver_option. + context.add_driver_option("-fPIC"); + } + rustc_target::spec::RelocModel::Pie => { + context.add_command_line_option("-fPIE"); + context.add_driver_option("-fPIE"); + } + model => eprintln!("Unsupported relocation model: {:?}", model), + } +} diff --git a/src/builder.rs b/src/builder.rs index 9a142326ad19..89e5cf1b8c6b 100644 --- a/src/builder.rs +++ b/src/builder.rs @@ -1102,18 +1102,24 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> { val: RValue<'gcc>, ptr: RValue<'gcc>, align: Align, - _flags: MemFlags, + flags: MemFlags, ) -> RValue<'gcc> { let ptr = self.check_store(val, ptr); let destination = ptr.dereference(self.location); // NOTE: libgccjit does not support specifying the alignment on the assignment, so we cast // to type so it gets the proper alignment. let destination_type = destination.to_rvalue().get_type().unqualified(); - let aligned_type = destination_type.get_aligned(align.bytes()).make_pointer(); - let aligned_destination = self.cx.context.new_bitcast(self.location, ptr, aligned_type); - let aligned_destination = aligned_destination.dereference(self.location); - self.llbb().add_assignment(self.location, aligned_destination, val); - // TODO(antoyo): handle align and flags. + let align = if flags.contains(MemFlags::UNALIGNED) { 1 } else { align.bytes() }; + let mut modified_destination_type = destination_type.get_aligned(align); + if flags.contains(MemFlags::VOLATILE) { + modified_destination_type = modified_destination_type.make_volatile(); + } + + let modified_ptr = + self.cx.context.new_cast(self.location, ptr, modified_destination_type.make_pointer()); + let modified_destination = modified_ptr.dereference(self.location); + self.llbb().add_assignment(self.location, modified_destination, val); + // TODO(antoyo): handle `MemFlags::NONTEMPORAL`. // NOTE: dummy value here since it's never used. FIXME(antoyo): API should not return a value here? // When adding support for NONTEMPORAL, make sure to not just emit MOVNT on x86; see the // LLVM backend for details. @@ -1236,13 +1242,13 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> { } fn ptrtoint(&mut self, value: RValue<'gcc>, dest_ty: Type<'gcc>) -> RValue<'gcc> { - let usize_value = self.cx.const_bitcast(value, self.cx.type_isize()); + let usize_value = self.cx.context.new_cast(None, value, self.cx.type_isize()); self.intcast(usize_value, dest_ty, false) } fn inttoptr(&mut self, value: RValue<'gcc>, dest_ty: Type<'gcc>) -> RValue<'gcc> { let usize_value = self.intcast(value, self.cx.type_isize(), false); - self.cx.const_bitcast(usize_value, dest_ty) + self.cx.context.new_cast(None, usize_value, dest_ty) } fn bitcast(&mut self, value: RValue<'gcc>, dest_ty: Type<'gcc>) -> RValue<'gcc> { @@ -1901,6 +1907,15 @@ impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> { v2: RValue<'gcc>, mask: RValue<'gcc>, ) -> RValue<'gcc> { + // NOTE: if the `mask` is a constant value, the following code will copy it in many places, + // which will make GCC create a lot (+4000) local variables in some cases. + // So we assign it to an explicit local variable once to avoid this. + let func = self.current_func(); + let mask_var = func.new_local(self.location, mask.get_type(), "mask"); + let block = self.block; + block.add_assignment(self.location, mask_var, mask); + let mask = mask_var.to_rvalue(); + // TODO(antoyo): use a recursive unqualified() here. let vector_type = v1.get_type().unqualified().dyncast_vector().expect("vector type"); let element_type = vector_type.get_element_type(); @@ -1917,18 +1932,35 @@ impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> { self.int_type }; - let vector_type = - mask.get_type().dyncast_vector().expect("simd_shuffle mask should be of vector type"); - let mask_num_units = vector_type.get_num_units(); - let mut mask_elements = vec![]; - for i in 0..mask_num_units { - let index = self.context.new_rvalue_from_long(self.cx.type_u32(), i as _); - mask_elements.push(self.context.new_cast( - self.location, - self.extract_element(mask, index).to_rvalue(), - mask_element_type, - )); - } + // NOTE: this condition is needed because we call shuffle_vector in the implementation of + // simd_gather. + let mut mask_elements = if let Some(vector_type) = mask.get_type().dyncast_vector() { + let mask_num_units = vector_type.get_num_units(); + let mut mask_elements = vec![]; + for i in 0..mask_num_units { + let index = self.context.new_rvalue_from_long(self.cx.type_u32(), i as _); + mask_elements.push(self.context.new_cast( + self.location, + self.extract_element(mask, index).to_rvalue(), + mask_element_type, + )); + } + mask_elements + } else { + let struct_type = mask.get_type().is_struct().expect("mask should be of struct type"); + let mask_num_units = struct_type.get_field_count(); + let mut mask_elements = vec![]; + for i in 0..mask_num_units { + let field = struct_type.get_field(i as i32); + mask_elements.push(self.context.new_cast( + self.location, + mask.access_field(self.location, field).to_rvalue(), + mask_element_type, + )); + } + mask_elements + }; + let mask_num_units = mask_elements.len(); // NOTE: the mask needs to be the same length as the input vectors, so add the missing // elements in the mask if needed. diff --git a/src/callee.rs b/src/callee.rs index 65972a03e835..c133ae4fcdd2 100644 --- a/src/callee.rs +++ b/src/callee.rs @@ -72,95 +72,74 @@ pub fn get_fn<'gcc, 'tcx>(cx: &CodegenCx<'gcc, 'tcx>, instance: Instance<'tcx>) attributes::from_fn_attrs(cx, func, instance); - let instance_def_id = instance.def_id(); + #[cfg(feature = "master")] + { + let instance_def_id = instance.def_id(); - // TODO(antoyo): set linkage and attributes. + // TODO(antoyo): set linkage and attributes. - // Apply an appropriate linkage/visibility value to our item that we - // just declared. - // - // This is sort of subtle. Inside our codegen unit we started off - // compilation by predefining all our own `MonoItem` instances. That - // is, everything we're codegenning ourselves is already defined. That - // means that anything we're actually codegenning in this codegen unit - // will have hit the above branch in `get_declared_value`. As a result, - // we're guaranteed here that we're declaring a symbol that won't get - // defined, or in other words we're referencing a value from another - // codegen unit or even another crate. - // - // So because this is a foreign value we blanket apply an external - // linkage directive because it's coming from a different object file. - // The visibility here is where it gets tricky. This symbol could be - // referencing some foreign crate or foreign library (an `extern` - // block) in which case we want to leave the default visibility. We may - // also, though, have multiple codegen units. It could be a - // monomorphization, in which case its expected visibility depends on - // whether we are sharing generics or not. The important thing here is - // that the visibility we apply to the declaration is the same one that - // has been applied to the definition (wherever that definition may be). - let is_generic = instance.args.non_erasable_generics().next().is_some(); + // Apply an appropriate linkage/visibility value to our item that we + // just declared. + // + // This is sort of subtle. Inside our codegen unit we started off + // compilation by predefining all our own `MonoItem` instances. That + // is, everything we're codegenning ourselves is already defined. That + // means that anything we're actually codegenning in this codegen unit + // will have hit the above branch in `get_declared_value`. As a result, + // we're guaranteed here that we're declaring a symbol that won't get + // defined, or in other words we're referencing a value from another + // codegen unit or even another crate. + // + // So because this is a foreign value we blanket apply an external + // linkage directive because it's coming from a different object file. + // The visibility here is where it gets tricky. This symbol could be + // referencing some foreign crate or foreign library (an `extern` + // block) in which case we want to leave the default visibility. We may + // also, though, have multiple codegen units. It could be a + // monomorphization, in which case its expected visibility depends on + // whether we are sharing generics or not. The important thing here is + // that the visibility we apply to the declaration is the same one that + // has been applied to the definition (wherever that definition may be). + let is_generic = instance.args.non_erasable_generics().next().is_some(); - if is_generic { - // This is a monomorphization. Its expected visibility depends - // on whether we are in share-generics mode. - - if cx.tcx.sess.opts.share_generics() { - // We are in share_generics mode. - - if let Some(instance_def_id) = instance_def_id.as_local() { - // This is a definition from the current crate. If the - // definition is unreachable for downstream crates or - // the current crate does not re-export generics, the - // definition of the instance will have been declared - // as `hidden`. - if cx.tcx.is_unreachable_local_definition(instance_def_id) + let is_hidden = if is_generic { + // This is a monomorphization of a generic function. + if !(cx.tcx.sess.opts.share_generics() + || tcx.codegen_fn_attrs(instance_def_id).inline + == rustc_attr_parsing::InlineAttr::Never) + { + // When not sharing generics, all instances are in the same + // crate and have hidden visibility. + true + } else if let Some(instance_def_id) = instance_def_id.as_local() { + // This is a monomorphization of a generic function + // defined in the current crate. It is hidden if: + // - the definition is unreachable for downstream + // crates, or + // - the current crate does not re-export generics + // (because the crate is a C library or executable) + cx.tcx.is_unreachable_local_definition(instance_def_id) || !cx.tcx.local_crate_exports_generics() - { - #[cfg(feature = "master")] - func.add_attribute(FnAttribute::Visibility(Visibility::Hidden)); - } } else { // This is a monomorphization of a generic function - // defined in an upstream crate. - if instance.upstream_monomorphization(tcx).is_some() { - // This is instantiated in another crate. It cannot - // be `hidden`. - } else { - // This is a local instantiation of an upstream definition. - // If the current crate does not re-export it - // (because it is a C library or an executable), it - // will have been declared `hidden`. - if !cx.tcx.local_crate_exports_generics() { - #[cfg(feature = "master")] - func.add_attribute(FnAttribute::Visibility(Visibility::Hidden)); - } - } + // defined in an upstream crate. It is hidden if: + // - it is instantiated in this crate, and + // - the current crate does not re-export generics + instance.upstream_monomorphization(tcx).is_none() + && !cx.tcx.local_crate_exports_generics() } } else { - // When not sharing generics, all instances are in the same - // crate and have hidden visibility - #[cfg(feature = "master")] + // This is a non-generic function. It is hidden if: + // - it is instantiated in the local crate, and + // - it is defined an upstream crate (non-local), or + // - it is not reachable + cx.tcx.is_codegened_item(instance_def_id) + && (!instance_def_id.is_local() + || !cx.tcx.is_reachable_non_generic(instance_def_id)) + }; + if is_hidden { func.add_attribute(FnAttribute::Visibility(Visibility::Hidden)); } - } else { - // This is a non-generic function - if cx.tcx.is_codegened_item(instance_def_id) { - // This is a function that is instantiated in the local crate - - if instance_def_id.is_local() { - // This is function that is defined in the local crate. - // If it is not reachable, it is hidden. - if !cx.tcx.is_reachable_non_generic(instance_def_id) { - #[cfg(feature = "master")] - func.add_attribute(FnAttribute::Visibility(Visibility::Hidden)); - } - } else { - // This is a function from an upstream crate that has - // been instantiated here. These are always hidden. - #[cfg(feature = "master")] - func.add_attribute(FnAttribute::Visibility(Visibility::Hidden)); - } - } } func diff --git a/src/common.rs b/src/common.rs index 0d3e7083d56a..f43743fc2a41 100644 --- a/src/common.rs +++ b/src/common.rs @@ -240,14 +240,14 @@ impl<'gcc, 'tcx> ConstCodegenMethods<'tcx> for CodegenCx<'gcc, 'tcx> { } }; let ptr_type = base_addr.get_type(); - let base_addr = self.const_bitcast(base_addr, self.usize_type); + let base_addr = self.context.new_cast(None, base_addr, self.usize_type); let offset = self.context.new_rvalue_from_long(self.usize_type, offset.bytes() as i64); - let ptr = self.const_bitcast(base_addr + offset, ptr_type); + let ptr = self.context.new_cast(None, base_addr + offset, ptr_type); if !matches!(layout.primitive(), Pointer(_)) { self.const_bitcast(ptr.dereference(None).to_rvalue(), ty) } else { - self.const_bitcast(ptr, ty) + self.context.new_cast(None, ptr, ty) } } } diff --git a/src/consts.rs b/src/consts.rs index 6dc2f4ed6688..1631ecfeecf3 100644 --- a/src/consts.rs +++ b/src/consts.rs @@ -252,7 +252,7 @@ impl<'gcc, 'tcx> CodegenCx<'gcc, 'tcx> { let global = self.declare_global( sym, gcc_type, - GlobalKind::Exported, + GlobalKind::Imported, is_tls, fn_attrs.link_section, ); @@ -404,7 +404,6 @@ fn check_and_apply_linkage<'gcc, 'tcx>( // TODO(antoyo): set linkage. let value = cx.const_ptrcast(global1.get_address(None), gcc_type); global2.global_set_initializer_rvalue(value); - // TODO(antoyo): use global_set_initializer() when it will work. global2 } else { // Generate an external declaration. diff --git a/src/context.rs b/src/context.rs index f67dcf0cb116..c81c53359fd1 100644 --- a/src/context.rs +++ b/src/context.rs @@ -386,6 +386,7 @@ impl<'gcc, 'tcx> CodegenCx<'gcc, 'tcx> { impl<'gcc, 'tcx> BackendTypes for CodegenCx<'gcc, 'tcx> { type Value = RValue<'gcc>; type Metadata = RValue<'gcc>; + // TODO(antoyo): change to Function<'gcc>. type Function = RValue<'gcc>; type BasicBlock = Block<'gcc>; diff --git a/src/errors.rs b/src/errors.rs index c896246866b9..1b59b9ac169a 100644 --- a/src/errors.rs +++ b/src/errors.rs @@ -40,10 +40,6 @@ pub(crate) enum PossibleFeature<'a> { None, } -#[derive(Diagnostic)] -#[diag(codegen_gcc_lto_not_supported)] -pub(crate) struct LTONotSupported; - #[derive(Diagnostic)] #[diag(codegen_gcc_unwinding_inline_asm)] pub(crate) struct UnwindingInlineAsm { diff --git a/src/gcc_util.rs b/src/gcc_util.rs index 1994a2a3c537..560aff43d653 100644 --- a/src/gcc_util.rs +++ b/src/gcc_util.rs @@ -66,16 +66,14 @@ pub(crate) fn global_gcc_features(sess: &Session, diagnostics: bool) -> Vec. all_rust_features.push((false, feature)); - } else if !feature.is_empty() { - if diagnostics { - sess.dcx().emit_warn(UnknownCTargetFeaturePrefix { feature }); - } + } else if !feature.is_empty() && diagnostics { + sess.dcx().emit_warn(UnknownCTargetFeaturePrefix { feature }); } } // Remove features that are meant for rustc, not codegen. - all_rust_features.retain(|(_, feature)| { + all_rust_features.retain(|&(_, feature)| { // Retain if it is not a rustc feature - !RUSTC_SPECIFIC_FEATURES.contains(feature) + !RUSTC_SPECIFIC_FEATURES.contains(&feature) }); // Check feature validity. @@ -103,7 +101,7 @@ pub(crate) fn global_gcc_features(sess: &Session, diagnostics: bool) -> Vec { + Some(&(_, stability, _)) => { if let Err(reason) = stability.toggle_allowed() { sess.dcx().emit_warn(ForbiddenCTargetFeature { feature, @@ -165,29 +163,25 @@ pub(crate) fn global_gcc_features(sess: &Session, diagnostics: bool) -> Vec>(), - ) - }) - .flatten(); + to_gcc_features(sess, feature) + .iter() + .flat_map(|feat| to_gcc_features(sess, feat).into_iter()) + .map(|feature| { + if enable_disable == '-' { + format!("-{}", feature) + } else { + feature.to_string() + } + }) + .collect::>() + }); features.extend(feats); if diagnostics { diff --git a/src/int.rs b/src/int.rs index 02b760dc7334..7b9d1feb8d71 100644 --- a/src/int.rs +++ b/src/int.rs @@ -90,7 +90,7 @@ impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> { } } } - } else if a_type.is_vector() && a_type.is_vector() { + } else if a_type.is_vector() && b_type.is_vector() { a >> b } else if a_native && !b_native { self.gcc_lshr(a, self.gcc_int_cast(b, a_type)) @@ -660,7 +660,7 @@ impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> { } } } - } else if a_type.is_vector() && a_type.is_vector() { + } else if a_type.is_vector() && b_type.is_vector() { a << b } else if a_native && !b_native { self.gcc_shl(a, self.gcc_int_cast(b, a_type)) diff --git a/src/intrinsic/llvm.rs b/src/intrinsic/llvm.rs index 0a448ded6b1a..231307def291 100644 --- a/src/intrinsic/llvm.rs +++ b/src/intrinsic/llvm.rs @@ -421,7 +421,7 @@ pub fn adjust_intrinsic_arguments<'a, 'b, 'gcc, 'tcx>( | "__builtin_ia32_xsaveopt64" => { let new_args = args.to_vec(); let thirty_two = builder.context.new_rvalue_from_int(new_args[1].get_type(), 32); - let arg2 = new_args[1] << thirty_two | new_args[2]; + let arg2 = (new_args[1] << thirty_two) | new_args[2]; let arg2_type = gcc_func.get_param_type(1); let arg2 = builder.context.new_cast(None, arg2, arg2_type); args = vec![new_args[0], arg2].into(); diff --git a/src/intrinsic/mod.rs b/src/intrinsic/mod.rs index 78ec9741f578..11f9604c6d26 100644 --- a/src/intrinsic/mod.rs +++ b/src/intrinsic/mod.rs @@ -13,15 +13,16 @@ use rustc_codegen_ssa::common::IntPredicate; use rustc_codegen_ssa::errors::InvalidMonomorphization; use rustc_codegen_ssa::mir::operand::{OperandRef, OperandValue}; use rustc_codegen_ssa::mir::place::{PlaceRef, PlaceValue}; +use rustc_codegen_ssa::traits::BaseTypeCodegenMethods; +#[cfg(feature = "master")] +use rustc_codegen_ssa::traits::MiscCodegenMethods; use rustc_codegen_ssa::traits::{ ArgAbiBuilderMethods, BuilderMethods, ConstCodegenMethods, IntrinsicCallBuilderMethods, }; -#[cfg(feature = "master")] -use rustc_codegen_ssa::traits::{BaseTypeCodegenMethods, MiscCodegenMethods}; use rustc_middle::bug; -use rustc_middle::ty::layout::LayoutOf; #[cfg(feature = "master")] -use rustc_middle::ty::layout::{FnAbiOf, HasTyCtxt, HasTypingEnv}; +use rustc_middle::ty::layout::{FnAbiOf, HasTyCtxt}; +use rustc_middle::ty::layout::{HasTypingEnv, LayoutOf}; use rustc_middle::ty::{self, Instance, Ty}; use rustc_span::{Span, Symbol, sym}; use rustc_target::abi::HasDataLayout; @@ -139,6 +140,18 @@ impl<'a, 'gcc, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tc &args.iter().map(|arg| arg.immediate()).collect::>(), ) } + sym::fmaf16 => { + // TODO(antoyo): use the correct builtin for f16. + let func = self.cx.context.get_builtin_function("fmaf"); + let args: Vec<_> = args + .iter() + .map(|arg| { + self.cx.context.new_cast(self.location, arg.immediate(), self.cx.type_f32()) + }) + .collect(); + let result = self.cx.context.new_call(self.location, func, &args); + self.cx.context.new_cast(self.location, result, self.cx.type_f16()) + } sym::is_val_statically_known => { let a = args[0].immediate(); let builtin = self.context.get_builtin_function("__builtin_constant_p"); diff --git a/src/intrinsic/simd.rs b/src/intrinsic/simd.rs index 79d1a06dd467..1be452e5d05d 100644 --- a/src/intrinsic/simd.rs +++ b/src/intrinsic/simd.rs @@ -379,7 +379,7 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>( // Make sure this is actually a SIMD vector. let idx_ty = args[2].layout.ty; let n: u64 = if idx_ty.is_simd() - && matches!(idx_ty.simd_size_and_type(bx.cx.tcx).1.kind(), ty::Uint(ty::UintTy::U32)) + && matches!(*idx_ty.simd_size_and_type(bx.cx.tcx).1.kind(), ty::Uint(ty::UintTy::U32)) { idx_ty.simd_size_and_type(bx.cx.tcx).0 } else { @@ -829,6 +829,7 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>( | sym::simd_flog | sym::simd_floor | sym::simd_fma + | sym::simd_relaxed_fma | sym::simd_fpow | sym::simd_fpowi | sym::simd_fsin diff --git a/src/lib.rs b/src/lib.rs index 7329080ce1f7..f6ad0c79de54 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -27,6 +27,8 @@ // Some "regular" crates we want to share with rustc extern crate object; extern crate smallvec; +// FIXME(antoyo): clippy bug: remove the #[allow] when it's fixed. +#[allow(unused_extern_crates)] extern crate tempfile; #[macro_use] extern crate tracing; @@ -88,7 +90,6 @@ use std::sync::atomic::Ordering; use std::sync::{Arc, Mutex}; use back::lto::{ThinBuffer, ThinData}; -use errors::LTONotSupported; use gccjit::{CType, Context, OptimizationLevel}; #[cfg(feature = "master")] use gccjit::{TargetInfo, Version}; @@ -109,9 +110,10 @@ use rustc_middle::dep_graph::{WorkProduct, WorkProductId}; use rustc_middle::ty::TyCtxt; use rustc_middle::util::Providers; use rustc_session::Session; -use rustc_session::config::{Lto, OptLevel, OutputFilenames}; +use rustc_session::config::{OptLevel, OutputFilenames}; use rustc_span::Symbol; use rustc_span::fatal_error::FatalError; +use rustc_target::spec::RelocModel; use tempfile::TempDir; use crate::back::lto::ModuleBuffer; @@ -141,11 +143,15 @@ impl TargetInfo { false } - fn supports_128bit_int(&self) -> bool { - self.supports_128bit_integers.load(Ordering::SeqCst) - } - - fn supports_target_dependent_type(&self, _typ: CType) -> bool { + fn supports_target_dependent_type(&self, typ: CType) -> bool { + match typ { + CType::UInt128t | CType::Int128t => { + if self.supports_128bit_integers.load(Ordering::SeqCst) { + return true; + } + } + _ => (), + } false } } @@ -166,10 +172,6 @@ impl LockedTargetInfo { self.info.lock().expect("lock").cpu_supports(feature) } - fn supports_128bit_int(&self) -> bool { - self.info.lock().expect("lock").supports_128bit_int() - } - fn supports_target_dependent_type(&self, typ: CType) -> bool { self.info.lock().expect("lock").supports_target_dependent_type(typ) } @@ -202,10 +204,6 @@ impl CodegenBackend for GccCodegenBackend { #[cfg(feature = "master")] gccjit::set_global_personality_function_name(b"rust_eh_personality\0"); - if sess.lto() == Lto::Thin { - sess.dcx().emit_warn(LTONotSupported {}); - } - #[cfg(not(feature = "master"))] { let temp_dir = TempDir::new().expect("cannot create temporary directory"); @@ -297,6 +295,7 @@ impl ExtraBackendMethods for GccCodegenBackend { ) -> Self::Module { let mut mods = GccContext { context: Arc::new(SyncContext::new(new_context(tcx))), + relocation_model: tcx.sess.relocation_model(), should_combine_object_files: false, temp_dir: None, }; @@ -328,6 +327,9 @@ impl ExtraBackendMethods for GccCodegenBackend { pub struct GccContext { context: Arc, + /// This field is needed in order to be able to set the flag -fPIC when necessary when doing + /// LTO. + relocation_model: RelocModel, should_combine_object_files: bool, // Temporary directory used by LTO. We keep it here so that it's not removed before linking. temp_dir: Option, @@ -492,10 +494,10 @@ fn target_features_cfg( sess.target .rust_target_features() .iter() - .filter(|(_, gate, _)| gate.in_cfg()) - .filter_map(|(feature, gate, _)| { + .filter(|&&(_, gate, _)| gate.in_cfg()) + .filter_map(|&(feature, gate, _)| { if sess.is_nightly_build() || allow_unstable || gate.requires_nightly().is_none() { - Some(*feature) + Some(feature) } else { None } diff --git a/tests/failing-non-lto-tests.txt b/tests/failing-non-lto-tests.txt deleted file mode 100644 index 384dfdc26fb5..000000000000 --- a/tests/failing-non-lto-tests.txt +++ /dev/null @@ -1,11 +0,0 @@ -tests/ui/issues/issue-44056.rs -tests/ui/lto/fat-lto.rs -tests/ui/lto/debuginfo-lto.rs -tests/ui/lto/lto-many-codegen-units.rs -tests/ui/lto/issue-100772.rs -tests/ui/lto/lto-rustc-loads-linker-plugin.rs -tests/ui/panic-runtime/lto-unwind.rs -tests/ui/sanitizer/issue-111184-cfi-coroutine-witness.rs -tests/ui/sepcomp/sepcomp-lib-lto.rs -tests/ui/lto/lto-opt-level-s.rs -tests/ui/lto/lto-opt-level-z.rs diff --git a/tests/failing-ui-tests.txt b/tests/failing-ui-tests.txt index 457072b1a5bc..082958bfe1f8 100644 --- a/tests/failing-ui-tests.txt +++ b/tests/failing-ui-tests.txt @@ -69,20 +69,22 @@ tests/ui/mir/mir_heavy_promoted.rs tests/ui/consts/const_cmp_type_id.rs tests/ui/consts/issue-73976-monomorphic.rs tests/ui/consts/issue-94675.rs -tests/ui/rfcs/rfc-2632-const-trait-impl/const-drop-fail.rs -tests/ui/rfcs/rfc-2632-const-trait-impl/const-drop.rs +tests/ui/traits/const-traits/const-drop-fail.rs +tests/ui/traits/const-traits/const-drop.rs tests/ui/runtime/on-broken-pipe/child-processes.rs -tests/ui/sanitizer/cfi-assoc-ty-lifetime-issue-123053.rs -tests/ui/sanitizer/cfi-async-closures.rs -tests/ui/sanitizer/cfi-closures.rs -tests/ui/sanitizer/cfi-complex-receiver.rs -tests/ui/sanitizer/cfi-coroutine.rs -tests/ui/sanitizer/cfi-drop-in-place.rs -tests/ui/sanitizer/cfi-drop-no-principal.rs -tests/ui/sanitizer/cfi-fn-ptr.rs -tests/ui/sanitizer/cfi-self-ref.rs -tests/ui/sanitizer/cfi-supertraits.rs -tests/ui/sanitizer/cfi-virtual-auto.rs +tests/ui/sanitizer/cfi/assoc-ty-lifetime-issue-123053.rs +tests/ui/sanitizer/cfi/async-closures.rs +tests/ui/sanitizer/cfi/closures.rs +tests/ui/sanitizer/cfi/complex-receiver.rs +tests/ui/sanitizer/cfi/coroutine.rs +tests/ui/sanitizer/cfi/drop-in-place.rs +tests/ui/sanitizer/cfi/drop-no-principal.rs +tests/ui/sanitizer/cfi/fn-ptr.rs +tests/ui/sanitizer/cfi/self-ref.rs +tests/ui/sanitizer/cfi/supertraits.rs +tests/ui/sanitizer/cfi/virtual-auto.rs +tests/ui/sanitizer/cfi/sized-associated-ty.rs +tests/ui/sanitizer/cfi/can-reveal-opaques.rs tests/ui/sanitizer/kcfi-mangling.rs tests/ui/statics/const_generics.rs tests/ui/backtrace/dylib-dep.rs @@ -91,6 +93,7 @@ tests/ui/delegation/fn-header.rs tests/ui/consts/zst_no_llvm_alloc.rs tests/ui/consts/const-eval/parse_ints.rs tests/ui/simd/intrinsic/generic-arithmetic-pass.rs +tests/ui/simd/intrinsic/generic-as.rs tests/ui/backtrace/backtrace.rs tests/ui/lifetimes/tail-expr-lock-poisoning.rs tests/ui/runtime/rt-explody-panic-payloads.rs @@ -118,5 +121,4 @@ tests/ui/codegen/equal-pointers-unequal/strict-provenance/print3.rs tests/ui/codegen/equal-pointers-unequal/strict-provenance/inline2.rs tests/ui/codegen/equal-pointers-unequal/strict-provenance/segfault.rs tests/ui/codegen/equal-pointers-unequal/strict-provenance/zero.rs -tests/ui/sanitizer/cfi-sized-associated-ty.rs -tests/ui/sanitizer/cfi-can-reveal-opaques.rs +tests/ui/simd/simd-bitmask-notpow2.rs diff --git a/tests/failing-ui-tests12.txt b/tests/failing-ui-tests12.txt index 1d9bdaa552c6..b10d4bc82aa8 100644 --- a/tests/failing-ui-tests12.txt +++ b/tests/failing-ui-tests12.txt @@ -11,7 +11,6 @@ tests/ui/simd/array-type.rs tests/ui/simd/intrinsic/float-minmax-pass.rs tests/ui/simd/intrinsic/generic-arithmetic-pass.rs tests/ui/simd/intrinsic/generic-arithmetic-saturating-pass.rs -tests/ui/simd/intrinsic/generic-as.rs tests/ui/simd/intrinsic/generic-cast-pass.rs tests/ui/simd/intrinsic/generic-cast-pointer-width.rs tests/ui/simd/intrinsic/generic-comparison-pass.rs diff --git a/tests/hello-world/Cargo.lock b/tests/hello-world/Cargo.lock new file mode 100644 index 000000000000..fe252db44253 --- /dev/null +++ b/tests/hello-world/Cargo.lock @@ -0,0 +1,14 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 4 + +[[package]] +name = "hello_world" +version = "0.0.0" +dependencies = [ + "mylib", +] + +[[package]] +name = "mylib" +version = "0.1.0" diff --git a/tests/hello-world/Cargo.toml b/tests/hello-world/Cargo.toml index 0b8cdc63fbe8..c6e22f642f67 100644 --- a/tests/hello-world/Cargo.toml +++ b/tests/hello-world/Cargo.toml @@ -1,4 +1,12 @@ [package] name = "hello_world" +edition = "2024" [dependencies] +mylib = { path = "mylib" } + +[profile.dev] +lto = "thin" + +[profile.release] +lto = "fat" diff --git a/tests/hello-world/mylib/Cargo.lock b/tests/hello-world/mylib/Cargo.lock new file mode 100644 index 000000000000..c8a0bfc63547 --- /dev/null +++ b/tests/hello-world/mylib/Cargo.lock @@ -0,0 +1,5 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "mylib" +version = "0.1.0" diff --git a/tests/hello-world/mylib/Cargo.toml b/tests/hello-world/mylib/Cargo.toml new file mode 100644 index 000000000000..d15f62bfb6dc --- /dev/null +++ b/tests/hello-world/mylib/Cargo.toml @@ -0,0 +1,9 @@ +[package] +name = "mylib" +version = "0.1.0" +authors = ["Antoni Boucher "] +edition = "2018" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] diff --git a/tests/hello-world/mylib/src/lib.rs b/tests/hello-world/mylib/src/lib.rs new file mode 100644 index 000000000000..8d3d111bd199 --- /dev/null +++ b/tests/hello-world/mylib/src/lib.rs @@ -0,0 +1,7 @@ +pub fn my_func(a: i32, b: i32) -> i32 { + let mut res = a; + for i in a..b { + res += i; + } + res +} diff --git a/tests/hello-world/src/main.rs b/tests/hello-world/src/main.rs index e7a11a969c03..71c78d364ac8 100644 --- a/tests/hello-world/src/main.rs +++ b/tests/hello-world/src/main.rs @@ -1,3 +1,5 @@ +use mylib::my_func; + fn main() { - println!("Hello, world!"); + println!("{}", my_func(5, 10)); } diff --git a/tests/lang_tests_common.rs b/tests/lang_tests_common.rs index aecea37ab5a9..fafb7be55ceb 100644 --- a/tests/lang_tests_common.rs +++ b/tests/lang_tests_common.rs @@ -22,14 +22,20 @@ pub fn main_inner(profile: Profile) { let tempdir = TempDir::new().expect("temp dir"); let current_dir = current_dir().expect("current dir"); let current_dir = current_dir.to_str().expect("current dir").to_string(); - let toml = Toml::parse(include_str!("../config.toml")).expect("Failed to parse `config.toml`"); - let gcc_path = if let Ok(gcc_path) = toml.get_string("gcc-path") { - PathBuf::from(gcc_path.to_string()) - } else { - // then we try to retrieve it from the `target` folder. - let commit = include_str!("../libgccjit.version").trim(); - Path::new("build/libgccjit").join(commit) - }; + + let manifest_dir = Path::new(env!("CARGO_MANIFEST_DIR")); + + let gcc_path = std::fs::read_to_string(manifest_dir.join("config.toml")) + .ok() + .and_then(|v| { + let toml = Toml::parse(&v).expect("Failed to parse `config.toml`"); + toml.get_string("gcc-path").map(PathBuf::from).ok() + }) + .unwrap_or_else(|| { + // then we try to retrieve it from the `target` folder. + let commit = include_str!("../libgccjit.version").trim(); + Path::new("build/libgccjit").join(commit) + }); let gcc_path = Path::new(&gcc_path) .canonicalize() @@ -83,6 +89,8 @@ pub fn main_inner(profile: Profile) { &format!("{}/build/build_sysroot/sysroot/", current_dir), "-C", "link-arg=-lc", + "--extern", + "mini_core=target/out/libmini_core.rlib", "-o", exe.to_str().expect("to_str"), path.to_str().expect("to_str"), diff --git a/tests/run/array.rs b/tests/run/array.rs index d8de9f28d4cb..c3c08c29c6db 100644 --- a/tests/run/array.rs +++ b/tests/run/array.rs @@ -7,38 +7,12 @@ // 5 // 10 -#![feature(arbitrary_self_types, auto_traits, lang_items, no_core, start, intrinsics, rustc_attrs)] -#![allow(internal_features)] +#![feature(no_core, start)] #![no_std] #![no_core] -/* - * Core - */ - -// Because we don't have core yet. -#[lang = "sized"] -pub trait Sized {} - -#[lang = "copy"] -trait Copy { -} - -impl Copy for isize {} -impl Copy for usize {} -impl Copy for i32 {} -impl Copy for u8 {} -impl Copy for i8 {} -impl Copy for i16 {} -impl Copy for *mut T {} - -#[lang = "receiver"] -trait Receiver { -} - -#[lang = "freeze"] -pub(crate) unsafe auto trait Freeze {} +extern crate mini_core; mod libc { #[link(name = "c")] @@ -48,182 +22,6 @@ mod libc { } } -#[lang = "index"] -pub trait Index { - type Output: ?Sized; - fn index(&self, index: Idx) -> &Self::Output; -} - -impl Index for [T; 3] { - type Output = T; - - fn index(&self, index: usize) -> &Self::Output { - &self[index] - } -} - -impl Index for [T] { - type Output = T; - - fn index(&self, index: usize) -> &Self::Output { - &self[index] - } -} - -#[lang = "drop_in_place"] -#[allow(unconditional_recursion)] -pub unsafe fn drop_in_place(to_drop: *mut T) { - // Code here does not matter - this is replaced by the - // real drop glue by the compiler. - drop_in_place(to_drop); -} - -#[lang = "panic"] -#[track_caller] -#[no_mangle] -pub fn panic(_msg: &'static str) -> ! { - unsafe { - libc::puts("Panicking\0" as *const str as *const u8); - intrinsics::abort(); - } -} - -#[lang = "panic_location"] -struct PanicLocation { - file: &'static str, - line: u32, - column: u32, -} - -#[lang = "panic_bounds_check"] -#[track_caller] -#[no_mangle] -fn panic_bounds_check(index: usize, len: usize) -> ! { - unsafe { - libc::printf("index out of bounds: the len is %d but the index is %d\n\0" as *const str as *const i8, len, index); - intrinsics::abort(); - } -} - -mod intrinsics { - #[rustc_nounwind] - #[rustc_intrinsic] - #[rustc_intrinsic_must_be_overridden] - pub fn abort() -> ! { - loop {} - } -} - -#[lang = "add"] -trait Add { - type Output; - - fn add(self, rhs: RHS) -> Self::Output; -} - -impl Add for u8 { - type Output = Self; - - fn add(self, rhs: Self) -> Self { - self + rhs - } -} - -impl Add for i8 { - type Output = Self; - - fn add(self, rhs: Self) -> Self { - self + rhs - } -} - -impl Add for i32 { - type Output = Self; - - fn add(self, rhs: Self) -> Self { - self + rhs - } -} - -impl Add for usize { - type Output = Self; - - fn add(self, rhs: Self) -> Self { - self + rhs - } -} - -impl Add for isize { - type Output = Self; - - fn add(self, rhs: Self) -> Self { - self + rhs - } -} - -#[lang = "sub"] -pub trait Sub { - type Output; - - fn sub(self, rhs: RHS) -> Self::Output; -} - -impl Sub for usize { - type Output = Self; - - fn sub(self, rhs: Self) -> Self { - self - rhs - } -} - -impl Sub for isize { - type Output = Self; - - fn sub(self, rhs: Self) -> Self { - self - rhs - } -} - -impl Sub for u8 { - type Output = Self; - - fn sub(self, rhs: Self) -> Self { - self - rhs - } -} - -impl Sub for i8 { - type Output = Self; - - fn sub(self, rhs: Self) -> Self { - self - rhs - } -} - -impl Sub for i16 { - type Output = Self; - - fn sub(self, rhs: Self) -> Self { - self - rhs - } -} - -#[track_caller] -#[lang = "panic_const_add_overflow"] -pub fn panic_const_add_overflow() -> ! { - panic("attempt to add with overflow"); -} - -#[track_caller] -#[lang = "panic_const_sub_overflow"] -pub fn panic_const_sub_overflow() -> ! { - panic("attempt to subtract with overflow"); -} - -/* - * Code - */ - static mut ONE: usize = 1; fn make_array() -> [u8; 3] { diff --git a/tests/run/closure.rs b/tests/run/closure.rs index b0d0ca4ee8df..46c47bc54ed0 100644 --- a/tests/run/closure.rs +++ b/tests/run/closure.rs @@ -8,200 +8,20 @@ // Int argument: 2 // Both args: 11 -#![feature(arbitrary_self_types, auto_traits, lang_items, no_core, start, intrinsics, - unboxed_closures, rustc_attrs)] -#![allow(internal_features)] +#![feature(no_core, start)] #![no_std] #![no_core] -/* - * Core - */ - -// Because we don't have core yet. -#[lang = "sized"] -pub trait Sized {} - -#[lang = "copy"] -trait Copy { -} - -impl Copy for isize {} -impl Copy for usize {} -impl Copy for i32 {} -impl Copy for u32 {} -impl Copy for u8 {} -impl Copy for i8 {} -impl Copy for *mut T {} - -#[lang = "receiver"] -trait Receiver { -} - -#[lang = "freeze"] -pub(crate) unsafe auto trait Freeze {} +extern crate mini_core; mod libc { #[link(name = "c")] extern "C" { - pub fn puts(s: *const u8) -> i32; pub fn printf(format: *const i8, ...) -> i32; } } -#[lang = "index"] -pub trait Index { - type Output: ?Sized; - fn index(&self, index: Idx) -> &Self::Output; -} - -impl Index for [T; 3] { - type Output = T; - - fn index(&self, index: usize) -> &Self::Output { - &self[index] - } -} - -impl Index for [T] { - type Output = T; - - fn index(&self, index: usize) -> &Self::Output { - &self[index] - } -} - -#[lang = "drop_in_place"] -#[allow(unconditional_recursion)] -pub unsafe fn drop_in_place(to_drop: *mut T) { - // Code here does not matter - this is replaced by the - // real drop glue by the compiler. - drop_in_place(to_drop); -} - -#[lang = "panic_location"] -struct PanicLocation { - file: &'static str, - line: u32, - column: u32, -} - -#[lang = "panic_bounds_check"] -#[track_caller] -#[no_mangle] -fn panic_bounds_check(index: usize, len: usize) -> ! { - unsafe { - libc::printf("index out of bounds: the len is %d but the index is %d\n\0" as *const str as *const i8, len, index); - intrinsics::abort(); - } -} - -mod intrinsics { - #[rustc_nounwind] - #[rustc_intrinsic] - #[rustc_intrinsic_must_be_overridden] - pub fn abort() -> ! { - loop {} - } -} - -#[lang = "tuple_trait"] -pub trait Tuple {} - -#[lang = "unsize"] -pub trait Unsize {} - -#[lang = "coerce_unsized"] -pub trait CoerceUnsized {} - -impl<'a, 'b: 'a, T: ?Sized + Unsize, U: ?Sized> CoerceUnsized<&'a U> for &'b T {} -impl<'a, T: ?Sized + Unsize, U: ?Sized> CoerceUnsized<&'a mut U> for &'a mut T {} -impl, U: ?Sized> CoerceUnsized<*const U> for *const T {} -impl, U: ?Sized> CoerceUnsized<*mut U> for *mut T {} - -#[lang = "fn_once"] -#[rustc_paren_sugar] -pub trait FnOnce { - #[lang = "fn_once_output"] - type Output; - - extern "rust-call" fn call_once(self, args: Args) -> Self::Output; -} - -#[lang = "fn_mut"] -#[rustc_paren_sugar] -pub trait FnMut: FnOnce { - extern "rust-call" fn call_mut(&mut self, args: Args) -> Self::Output; -} - -#[lang = "add"] -trait Add { - type Output; - - fn add(self, rhs: RHS) -> Self::Output; -} - -impl Add for u8 { - type Output = Self; - - fn add(self, rhs: Self) -> Self { - self + rhs - } -} - -impl Add for i8 { - type Output = Self; - - fn add(self, rhs: Self) -> Self { - self + rhs - } -} - -impl Add for i32 { - type Output = Self; - - fn add(self, rhs: Self) -> Self { - self + rhs - } -} - -impl Add for usize { - type Output = Self; - - fn add(self, rhs: Self) -> Self { - self + rhs - } -} - -impl Add for isize { - type Output = Self; - - fn add(self, rhs: Self) -> Self { - self + rhs - } -} - -#[lang = "panic"] -#[track_caller] -#[no_mangle] -pub fn panic(_msg: &'static str) -> ! { - unsafe { - libc::puts("Panicking\0" as *const str as *const u8); - intrinsics::abort(); - } -} - -#[track_caller] -#[lang = "panic_const_add_overflow"] -pub fn panic_const_add_overflow() -> ! { - panic("attempt to add with overflow"); -} - -/* - * Code - */ - #[start] fn main(mut argc: isize, _argv: *const *const u8) -> isize { let string = "Arg: %d\n\0"; diff --git a/tests/run/condition.rs b/tests/run/condition.rs index 770b18a89e3e..039ef94eaa71 100644 --- a/tests/run/condition.rs +++ b/tests/run/condition.rs @@ -5,304 +5,20 @@ // stdout: true // 1 -#![feature(arbitrary_self_types, auto_traits, lang_items, no_core, start, intrinsics, rustc_attrs)] -#![allow(internal_features)] +#![feature(no_core, start)] #![no_std] #![no_core] -/* - * Core - */ - -// Because we don't have core yet. -#[lang = "sized"] -pub trait Sized {} - -#[lang = "copy"] -trait Copy { -} - -impl Copy for isize {} -impl Copy for usize {} -impl Copy for u64 {} -impl Copy for i32 {} -impl Copy for u32 {} -impl Copy for bool {} -impl Copy for u16 {} -impl Copy for i16 {} -impl Copy for char {} -impl Copy for i8 {} -impl Copy for u8 {} -impl Copy for *mut T {} - -#[lang = "receiver"] -trait Receiver { -} - -#[lang = "freeze"] -pub(crate) unsafe auto trait Freeze {} +extern crate mini_core; mod libc { #[link(name = "c")] extern "C" { pub fn printf(format: *const i8, ...) -> i32; - pub fn puts(s: *const u8) -> i32; } } -#[lang = "index"] -pub trait Index { - type Output: ?Sized; - fn index(&self, index: Idx) -> &Self::Output; -} - -impl Index for [T; 3] { - type Output = T; - - fn index(&self, index: usize) -> &Self::Output { - &self[index] - } -} - -impl Index for [T] { - type Output = T; - - fn index(&self, index: usize) -> &Self::Output { - &self[index] - } -} - -#[lang = "drop_in_place"] -#[allow(unconditional_recursion)] -pub unsafe fn drop_in_place(to_drop: *mut T) { - // Code here does not matter - this is replaced by the - // real drop glue by the compiler. - drop_in_place(to_drop); -} - -#[lang = "panic"] -#[track_caller] -#[no_mangle] -pub fn panic(_msg: &'static str) -> ! { - unsafe { - libc::puts("Panicking\0" as *const str as *const u8); - intrinsics::abort(); - } -} - -#[lang = "panic_location"] -struct PanicLocation { - file: &'static str, - line: u32, - column: u32, -} - -#[lang = "panic_bounds_check"] -#[track_caller] -#[no_mangle] -fn panic_bounds_check(index: usize, len: usize) -> ! { - unsafe { - libc::printf("index out of bounds: the len is %d but the index is %d\n\0" as *const str as *const i8, len, index); - intrinsics::abort(); - } -} - -mod intrinsics { - #[rustc_nounwind] - #[rustc_intrinsic] - #[rustc_intrinsic_must_be_overridden] - pub fn abort() -> ! { - loop {} - } -} - -#[lang = "add"] -trait Add { - type Output; - - fn add(self, rhs: RHS) -> Self::Output; -} - -impl Add for u8 { - type Output = Self; - - fn add(self, rhs: Self) -> Self { - self + rhs - } -} - -impl Add for i8 { - type Output = Self; - - fn add(self, rhs: Self) -> Self { - self + rhs - } -} - -impl Add for i32 { - type Output = Self; - - fn add(self, rhs: Self) -> Self { - self + rhs - } -} - -impl Add for usize { - type Output = Self; - - fn add(self, rhs: Self) -> Self { - self + rhs - } -} - -impl Add for isize { - type Output = Self; - - fn add(self, rhs: Self) -> Self { - self + rhs - } -} - -#[lang = "sub"] -pub trait Sub { - type Output; - - fn sub(self, rhs: RHS) -> Self::Output; -} - -impl Sub for usize { - type Output = Self; - - fn sub(self, rhs: Self) -> Self { - self - rhs - } -} - -impl Sub for isize { - type Output = Self; - - fn sub(self, rhs: Self) -> Self { - self - rhs - } -} - -impl Sub for u8 { - type Output = Self; - - fn sub(self, rhs: Self) -> Self { - self - rhs - } -} - -impl Sub for i8 { - type Output = Self; - - fn sub(self, rhs: Self) -> Self { - self - rhs - } -} - -impl Sub for i16 { - type Output = Self; - - fn sub(self, rhs: Self) -> Self { - self - rhs - } -} - -#[lang = "eq"] -pub trait PartialEq { - fn eq(&self, other: &Rhs) -> bool; - fn ne(&self, other: &Rhs) -> bool; -} - -impl PartialEq for u8 { - fn eq(&self, other: &u8) -> bool { - (*self) == (*other) - } - fn ne(&self, other: &u8) -> bool { - (*self) != (*other) - } -} - -impl PartialEq for u16 { - fn eq(&self, other: &u16) -> bool { - (*self) == (*other) - } - fn ne(&self, other: &u16) -> bool { - (*self) != (*other) - } -} - -impl PartialEq for u32 { - fn eq(&self, other: &u32) -> bool { - (*self) == (*other) - } - fn ne(&self, other: &u32) -> bool { - (*self) != (*other) - } -} - - -impl PartialEq for u64 { - fn eq(&self, other: &u64) -> bool { - (*self) == (*other) - } - fn ne(&self, other: &u64) -> bool { - (*self) != (*other) - } -} - -impl PartialEq for usize { - fn eq(&self, other: &usize) -> bool { - (*self) == (*other) - } - fn ne(&self, other: &usize) -> bool { - (*self) != (*other) - } -} - -impl PartialEq for i8 { - fn eq(&self, other: &i8) -> bool { - (*self) == (*other) - } - fn ne(&self, other: &i8) -> bool { - (*self) != (*other) - } -} - -impl PartialEq for i32 { - fn eq(&self, other: &i32) -> bool { - (*self) == (*other) - } - fn ne(&self, other: &i32) -> bool { - (*self) != (*other) - } -} - -impl PartialEq for isize { - fn eq(&self, other: &isize) -> bool { - (*self) == (*other) - } - fn ne(&self, other: &isize) -> bool { - (*self) != (*other) - } -} - -impl PartialEq for char { - fn eq(&self, other: &char) -> bool { - (*self) == (*other) - } - fn ne(&self, other: &char) -> bool { - (*self) != (*other) - } -} - -/* - * Code - */ - #[start] fn main(argc: isize, _argv: *const *const u8) -> isize { unsafe { diff --git a/tests/run/fun_ptr.rs b/tests/run/fun_ptr.rs index 523544ee6bbb..ed1bf72bb275 100644 --- a/tests/run/fun_ptr.rs +++ b/tests/run/fun_ptr.rs @@ -4,212 +4,20 @@ // status: 0 // stdout: 1 -#![feature(arbitrary_self_types, auto_traits, lang_items, no_core, start, intrinsics, rustc_attrs)] -#![allow(internal_features)] +#![feature(no_core, start)] #![no_std] #![no_core] -/* - * Core - */ - -// Because we don't have core yet. -#[lang = "sized"] -pub trait Sized {} - -#[lang = "copy"] -trait Copy { -} - -impl Copy for isize {} -impl Copy for usize {} -impl Copy for i32 {} -impl Copy for u8 {} -impl Copy for i8 {} -impl Copy for i16 {} -impl Copy for *mut T {} - -#[lang = "receiver"] -trait Receiver { -} - -#[lang = "freeze"] -pub(crate) unsafe auto trait Freeze {} +extern crate mini_core; mod libc { #[link(name = "c")] extern "C" { pub fn printf(format: *const i8, ...) -> i32; - pub fn puts(s: *const u8) -> i32; } } -#[lang = "index"] -pub trait Index { - type Output: ?Sized; - fn index(&self, index: Idx) -> &Self::Output; -} - -impl Index for [T; 3] { - type Output = T; - - fn index(&self, index: usize) -> &Self::Output { - &self[index] - } -} - -impl Index for [T] { - type Output = T; - - fn index(&self, index: usize) -> &Self::Output { - &self[index] - } -} - -#[lang = "drop_in_place"] -#[allow(unconditional_recursion)] -pub unsafe fn drop_in_place(to_drop: *mut T) { - // Code here does not matter - this is replaced by the - // real drop glue by the compiler. - drop_in_place(to_drop); -} - -#[lang = "panic"] -#[track_caller] -#[no_mangle] -pub fn panic(_msg: &'static str) -> ! { - unsafe { - libc::puts("Panicking\0" as *const str as *const u8); - intrinsics::abort(); - } -} - -#[lang = "panic_location"] -struct PanicLocation { - file: &'static str, - line: u32, - column: u32, -} - -#[lang = "panic_bounds_check"] -#[track_caller] -#[no_mangle] -fn panic_bounds_check(index: usize, len: usize) -> ! { - unsafe { - libc::printf("index out of bounds: the len is %d but the index is %d\n\0" as *const str as *const i8, len, index); - intrinsics::abort(); - } -} - -mod intrinsics { - #[rustc_nounwind] - #[rustc_intrinsic] - #[rustc_intrinsic_must_be_overridden] - pub fn abort() -> ! { - loop {} - } -} - -#[lang = "add"] -trait Add { - type Output; - - fn add(self, rhs: RHS) -> Self::Output; -} - -impl Add for u8 { - type Output = Self; - - fn add(self, rhs: Self) -> Self { - self + rhs - } -} - -impl Add for i8 { - type Output = Self; - - fn add(self, rhs: Self) -> Self { - self + rhs - } -} - -impl Add for i32 { - type Output = Self; - - fn add(self, rhs: Self) -> Self { - self + rhs - } -} - -impl Add for usize { - type Output = Self; - - fn add(self, rhs: Self) -> Self { - self + rhs - } -} - -impl Add for isize { - type Output = Self; - - fn add(self, rhs: Self) -> Self { - self + rhs - } -} - -#[lang = "sub"] -pub trait Sub { - type Output; - - fn sub(self, rhs: RHS) -> Self::Output; -} - -impl Sub for usize { - type Output = Self; - - fn sub(self, rhs: Self) -> Self { - self - rhs - } -} - -impl Sub for isize { - type Output = Self; - - fn sub(self, rhs: Self) -> Self { - self - rhs - } -} - -impl Sub for u8 { - type Output = Self; - - fn sub(self, rhs: Self) -> Self { - self - rhs - } -} - -impl Sub for i8 { - type Output = Self; - - fn sub(self, rhs: Self) -> Self { - self - rhs - } -} - -impl Sub for i16 { - type Output = Self; - - fn sub(self, rhs: Self) -> Self { - self - rhs - } -} - - -/* - * Code - */ - fn i16_as_i8(a: i16) -> i8 { a as i8 } diff --git a/tests/run/operations.rs b/tests/run/operations.rs index 2e3c021d5f77..0e44fc580b8c 100644 --- a/tests/run/operations.rs +++ b/tests/run/operations.rs @@ -38,8 +38,8 @@ pub trait Deref { fn deref(&self) -> &Self::Target; } -#[lang = "receiver"] -trait Receiver { +#[lang = "legacy_receiver"] +trait LegacyReceiver { } #[lang = "freeze"] diff --git a/tests/run/ptr_cast.rs b/tests/run/ptr_cast.rs index c7510d16449e..2b8812ad51c5 100644 --- a/tests/run/ptr_cast.rs +++ b/tests/run/ptr_cast.rs @@ -4,212 +4,20 @@ // status: 0 // stdout: 1 -#![feature(arbitrary_self_types, auto_traits, lang_items, no_core, start, intrinsics, rustc_attrs)] -#![allow(internal_features)] +#![feature(no_core, start)] #![no_std] #![no_core] -/* - * Core - */ - -// Because we don't have core yet. -#[lang = "sized"] -pub trait Sized {} - -#[lang = "copy"] -trait Copy { -} - -impl Copy for isize {} -impl Copy for usize {} -impl Copy for i32 {} -impl Copy for u8 {} -impl Copy for i8 {} -impl Copy for i16 {} -impl Copy for *mut T {} - -#[lang = "receiver"] -trait Receiver { -} - -#[lang = "freeze"] -pub(crate) unsafe auto trait Freeze {} +extern crate mini_core; mod libc { #[link(name = "c")] extern "C" { pub fn printf(format: *const i8, ...) -> i32; - pub fn puts(s: *const u8) -> i32; } } -#[lang = "index"] -pub trait Index { - type Output: ?Sized; - fn index(&self, index: Idx) -> &Self::Output; -} - -impl Index for [T; 3] { - type Output = T; - - fn index(&self, index: usize) -> &Self::Output { - &self[index] - } -} - -impl Index for [T] { - type Output = T; - - fn index(&self, index: usize) -> &Self::Output { - &self[index] - } -} - -#[lang = "drop_in_place"] -#[allow(unconditional_recursion)] -pub unsafe fn drop_in_place(to_drop: *mut T) { - // Code here does not matter - this is replaced by the - // real drop glue by the compiler. - drop_in_place(to_drop); -} - -#[lang = "panic"] -#[track_caller] -#[no_mangle] -pub fn panic(_msg: &'static str) -> ! { - unsafe { - libc::puts("Panicking\0" as *const str as *const u8); - intrinsics::abort(); - } -} - -#[lang = "panic_location"] -struct PanicLocation { - file: &'static str, - line: u32, - column: u32, -} - -#[lang = "panic_bounds_check"] -#[track_caller] -#[no_mangle] -fn panic_bounds_check(index: usize, len: usize) -> ! { - unsafe { - libc::printf("index out of bounds: the len is %d but the index is %d\n\0" as *const str as *const i8, len, index); - intrinsics::abort(); - } -} - -mod intrinsics { - #[rustc_nounwind] - #[rustc_intrinsic] - #[rustc_intrinsic_must_be_overridden] - pub fn abort() -> ! { - loop {} - } -} - -#[lang = "add"] -trait Add { - type Output; - - fn add(self, rhs: RHS) -> Self::Output; -} - -impl Add for u8 { - type Output = Self; - - fn add(self, rhs: Self) -> Self { - self + rhs - } -} - -impl Add for i8 { - type Output = Self; - - fn add(self, rhs: Self) -> Self { - self + rhs - } -} - -impl Add for i32 { - type Output = Self; - - fn add(self, rhs: Self) -> Self { - self + rhs - } -} - -impl Add for usize { - type Output = Self; - - fn add(self, rhs: Self) -> Self { - self + rhs - } -} - -impl Add for isize { - type Output = Self; - - fn add(self, rhs: Self) -> Self { - self + rhs - } -} - -#[lang = "sub"] -pub trait Sub { - type Output; - - fn sub(self, rhs: RHS) -> Self::Output; -} - -impl Sub for usize { - type Output = Self; - - fn sub(self, rhs: Self) -> Self { - self - rhs - } -} - -impl Sub for isize { - type Output = Self; - - fn sub(self, rhs: Self) -> Self { - self - rhs - } -} - -impl Sub for u8 { - type Output = Self; - - fn sub(self, rhs: Self) -> Self { - self - rhs - } -} - -impl Sub for i8 { - type Output = Self; - - fn sub(self, rhs: Self) -> Self { - self - rhs - } -} - -impl Sub for i16 { - type Output = Self; - - fn sub(self, rhs: Self) -> Self { - self - rhs - } -} - - -/* - * Code - */ - static mut ONE: usize = 1; fn make_array() -> [u8; 3] { diff --git a/tests/run/return-tuple.rs b/tests/run/return-tuple.rs index 8d40deb8c85e..f2a5a2e4384d 100644 --- a/tests/run/return-tuple.rs +++ b/tests/run/return-tuple.rs @@ -15,18 +15,18 @@ #[lang = "copy"] pub unsafe trait Copy {} -unsafe impl Copy for bool {} -unsafe impl Copy for u8 {} -unsafe impl Copy for u16 {} -unsafe impl Copy for u32 {} -unsafe impl Copy for u64 {} -unsafe impl Copy for usize {} -unsafe impl Copy for i8 {} -unsafe impl Copy for i16 {} -unsafe impl Copy for i32 {} -unsafe impl Copy for isize {} -unsafe impl Copy for f32 {} -unsafe impl Copy for char {} +impl Copy for bool {} +impl Copy for u8 {} +impl Copy for u16 {} +impl Copy for u32 {} +impl Copy for u64 {} +impl Copy for usize {} +impl Copy for i8 {} +impl Copy for i16 {} +impl Copy for i32 {} +impl Copy for isize {} +impl Copy for f32 {} +impl Copy for char {} mod libc { #[link(name = "c")] @@ -43,8 +43,8 @@ mod libc { #[lang = "sized"] pub trait Sized {} -#[lang = "receiver"] -trait Receiver { +#[lang = "legacy_receiver"] +trait LegacyReceiver { } #[lang = "freeze"] diff --git a/tests/run/slice.rs b/tests/run/slice.rs index 35ad594ecdea..fba93fc15549 100644 --- a/tests/run/slice.rs +++ b/tests/run/slice.rs @@ -4,36 +4,12 @@ // status: 0 // stdout: 5 -#![feature(arbitrary_self_types, auto_traits, lang_items, no_core, start, intrinsics, rustc_attrs)] -#![allow(internal_features)] +#![feature(no_core, start)] #![no_std] #![no_core] -/* - * Core - */ - -// Because we don't have core yet. -#[lang = "sized"] -pub trait Sized {} - -#[lang = "copy"] -trait Copy { -} - -impl Copy for isize {} -impl Copy for usize {} -impl Copy for i32 {} -impl Copy for u32 {} -impl Copy for *mut T {} - -#[lang = "receiver"] -trait Receiver { -} - -#[lang = "freeze"] -pub(crate) unsafe auto trait Freeze {} +extern crate mini_core; mod libc { #[link(name = "c")] @@ -42,79 +18,6 @@ mod libc { } } -#[lang = "index"] -pub trait Index { - type Output: ?Sized; - fn index(&self, index: Idx) -> &Self::Output; -} - -impl Index for [T; 3] { - type Output = T; - - fn index(&self, index: usize) -> &Self::Output { - &self[index] - } -} - -impl Index for [T] { - type Output = T; - - fn index(&self, index: usize) -> &Self::Output { - &self[index] - } -} - -#[lang = "unsize"] -pub trait Unsize {} - -#[lang = "coerce_unsized"] -pub trait CoerceUnsized {} - -impl<'a, 'b: 'a, T: ?Sized + Unsize, U: ?Sized> CoerceUnsized<&'a U> for &'b T {} -impl<'a, T: ?Sized + Unsize, U: ?Sized> CoerceUnsized<&'a mut U> for &'a mut T {} -impl, U: ?Sized> CoerceUnsized<*const U> for *const T {} -impl, U: ?Sized> CoerceUnsized<*mut U> for *mut T {} - -#[lang = "drop_in_place"] -#[allow(unconditional_recursion)] -pub unsafe fn drop_in_place(to_drop: *mut T) { - // Code here does not matter - this is replaced by the - // real drop glue by the compiler. - drop_in_place(to_drop); -} - -#[lang = "panic_location"] -struct PanicLocation { - file: &'static str, - line: u32, - column: u32, -} - -#[lang = "panic_bounds_check"] -#[track_caller] -#[no_mangle] -fn panic_bounds_check(index: usize, len: usize) -> ! { - unsafe { - libc::printf("index out of bounds: the len is %d but the index is %d\n\0" as *const str as *const i8, len, index); - intrinsics::abort(); - } -} - -mod intrinsics { - use super::Sized; - - #[rustc_nounwind] - #[rustc_intrinsic] - #[rustc_intrinsic_must_be_overridden] - pub fn abort() -> ! { - loop {} - } -} - -/* - * Code - */ - static mut TWO: usize = 2; fn index_slice(s: &[u32]) -> u32 { diff --git a/tests/run/volatile2.rs b/tests/run/volatile2.rs new file mode 100644 index 000000000000..a177b817ab35 --- /dev/null +++ b/tests/run/volatile2.rs @@ -0,0 +1,113 @@ +// Compiler: +// +// Run-time: +// status: 0 + +mod libc { + #[link(name = "c")] + extern "C" { + pub fn puts(s: *const u8) -> i32; + + pub fn sigaction(signum: i32, act: *const sigaction, oldact: *mut sigaction) -> i32; + pub fn mmap(addr: *mut (), len: usize, prot: i32, flags: i32, fd: i32, offset: i64) -> *mut (); + pub fn mprotect(addr: *mut (), len: usize, prot: i32) -> i32; + } + + pub const PROT_READ: i32 = 1; + pub const PROT_WRITE: i32 = 2; + pub const MAP_PRIVATE: i32 = 0x0002; + pub const MAP_ANONYMOUS: i32 = 0x0020; + pub const MAP_FAILED: *mut u8 = !0 as *mut u8; + + /// glibc sigaction + #[repr(C)] + pub struct sigaction { + pub sa_sigaction: Option, + pub sa_mask: [u32; 32], + pub sa_flags: i32, + pub sa_restorer: Option, + } + + pub const SA_SIGINFO: i32 = 0x00000004; + pub const SIGSEGV: i32 = 11; +} + +static mut COUNT: u32 = 0; +static mut STORAGE: *mut u8 = core::ptr::null_mut(); +const PAGE_SIZE: usize = 1 << 15; + +fn main() { + unsafe { + // Register a segfault handler + libc::sigaction( + libc::SIGSEGV, + &libc::sigaction { + sa_sigaction: Some(segv_handler), + sa_flags: libc::SA_SIGINFO, + ..core::mem::zeroed() + }, + core::ptr::null_mut(), + ); + + STORAGE = libc::mmap( + core::ptr::null_mut(), + PAGE_SIZE * 2, + 0, + libc::MAP_PRIVATE | libc::MAP_ANONYMOUS, + -1, + 0, + ).cast(); + if STORAGE == libc::MAP_FAILED { + panic!("error: mmap failed"); + } + + let p_count = (&mut COUNT) as *mut u32; + p_count.write_volatile(0); + + // Trigger segfaults + STORAGE.add(0).write_volatile(1); + STORAGE.add(PAGE_SIZE).write_volatile(1); + STORAGE.add(0).write_volatile(1); + STORAGE.add(PAGE_SIZE).write_volatile(1); + STORAGE.add(0).write_volatile(1); + STORAGE.add(PAGE_SIZE).write_volatile(1); + STORAGE.add(0).read_volatile(); + STORAGE.add(PAGE_SIZE).read_volatile(); + STORAGE.add(0).read_volatile(); + STORAGE.add(PAGE_SIZE).read_volatile(); + STORAGE.add(0).read_volatile(); + STORAGE.add(PAGE_SIZE).read_volatile(); + STORAGE.add(0).write_volatile(1); + STORAGE.add(PAGE_SIZE).write_volatile(1); + + // The segfault handler should have been called for every `write_volatile` and + // `read_volatile` in `STORAGE`. If the compiler ignores volatility, some of these writes + // will be combined, causing a different number of segfaults. + // + // This `p_count` read is done by a volatile read. If the compiler + // ignores volatility, the compiler will speculate that `*p_count` is + // unchanged and remove this check, failing the test. + if p_count.read_volatile() != 14 { + panic!("error: segfault count mismatch: {}", p_count.read_volatile()); + } + } +} + +unsafe extern "C" fn segv_handler(_: i32, _: *mut (), _: *mut ()) { + let p_count = (&mut COUNT) as *mut u32; + p_count.write_volatile(p_count.read_volatile() + 1); + let count = p_count.read_volatile(); + + // Toggle the protected page so that the handler will be called for + // each `write_volatile` + libc::mprotect( + STORAGE.cast(), + PAGE_SIZE, + if count % 2 == 1 { libc::PROT_READ | libc::PROT_WRITE } else { 0 }, + ); + libc::mprotect( + STORAGE.add(PAGE_SIZE).cast(), + PAGE_SIZE, + if count % 2 == 0 { libc::PROT_READ | libc::PROT_WRITE } else { 0 }, + ); +} From f8b89a3d05e995bd293aaac35d97f4b18b54e8fe Mon Sep 17 00:00:00 2001 From: Antoni Boucher Date: Mon, 13 Jan 2025 11:48:14 -0500 Subject: [PATCH 03/81] Fix formatting --- .rustfmt.toml | 4 +++- src/intrinsic/mod.rs | 4 ++-- tests/lang_tests_common.rs | 8 +++----- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/.rustfmt.toml b/.rustfmt.toml index 725aec25a071..a11bc41680d2 100644 --- a/.rustfmt.toml +++ b/.rustfmt.toml @@ -1,3 +1,5 @@ -version = "Two" +style_edition = "2024" use_small_heuristics = "Max" merge_derives = false +group_imports = "StdExternalCrate" +imports_granularity = "Module" diff --git a/src/intrinsic/mod.rs b/src/intrinsic/mod.rs index 11f9604c6d26..42d189d1b7d3 100644 --- a/src/intrinsic/mod.rs +++ b/src/intrinsic/mod.rs @@ -13,11 +13,11 @@ use rustc_codegen_ssa::common::IntPredicate; use rustc_codegen_ssa::errors::InvalidMonomorphization; use rustc_codegen_ssa::mir::operand::{OperandRef, OperandValue}; use rustc_codegen_ssa::mir::place::{PlaceRef, PlaceValue}; -use rustc_codegen_ssa::traits::BaseTypeCodegenMethods; #[cfg(feature = "master")] use rustc_codegen_ssa::traits::MiscCodegenMethods; use rustc_codegen_ssa::traits::{ - ArgAbiBuilderMethods, BuilderMethods, ConstCodegenMethods, IntrinsicCallBuilderMethods, + ArgAbiBuilderMethods, BaseTypeCodegenMethods, BuilderMethods, ConstCodegenMethods, + IntrinsicCallBuilderMethods, }; use rustc_middle::bug; #[cfg(feature = "master")] diff --git a/tests/lang_tests_common.rs b/tests/lang_tests_common.rs index fafb7be55ceb..64c932a26581 100644 --- a/tests/lang_tests_common.rs +++ b/tests/lang_tests_common.rs @@ -1,10 +1,8 @@ //! The common code for `tests/lang_tests_*.rs` -use std::{ - env::{self, current_dir}, - path::{Path, PathBuf}, - process::Command, -}; +use std::env::{self, current_dir}; +use std::path::{Path, PathBuf}; +use std::process::Command; use boml::Toml; use lang_tester::LangTester; From 7bc67011d27f3e1ce15d8368f75365644549fbe8 Mon Sep 17 00:00:00 2001 From: Sudhanshu Singh Date: Mon, 13 Jan 2025 22:27:33 +0530 Subject: [PATCH 04/81] Remove codegen_gcc_lto_not_supported in messages.flt --- messages.ftl | 3 --- 1 file changed, 3 deletions(-) diff --git a/messages.ftl b/messages.ftl index 85fa17a6ba50..882fff8673a1 100644 --- a/messages.ftl +++ b/messages.ftl @@ -5,9 +5,6 @@ codegen_gcc_unknown_ctarget_feature_prefix = codegen_gcc_invalid_minimum_alignment = invalid minimum global alignment: {$err} -codegen_gcc_lto_not_supported = - LTO is not supported. You may get a linker error. - codegen_gcc_forbidden_ctarget_feature = target feature `{$feature}` cannot be toggled with `-Ctarget-feature`: {$reason} From 50a9f41ce97ec0c297d33611f1cd91e81bf1e519 Mon Sep 17 00:00:00 2001 From: Antoni Boucher Date: Wed, 15 Jan 2025 10:26:57 -0500 Subject: [PATCH 05/81] Update GCC version --- .github/workflows/ci.yml | 4 ++-- .github/workflows/failures.yml | 4 ++-- .github/workflows/m68k.yml | 6 +++--- .github/workflows/release.yml | 4 ++-- libgccjit.version | 2 +- 5 files changed, 10 insertions(+), 10 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 73ec6b84a155..fa6133c75e31 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -19,8 +19,8 @@ jobs: fail-fast: false matrix: libgccjit_version: - - { gcc: "gcc-13.deb" } - - { gcc: "gcc-13-without-int128.deb" } + - { gcc: "gcc-15.deb" } + - { gcc: "gcc-15-without-int128.deb" } commands: [ "--std-tests", # FIXME: re-enable asm tests when GCC can emit in the right syntax. diff --git a/.github/workflows/failures.yml b/.github/workflows/failures.yml index f33d9fcc5825..407c9b31d05c 100644 --- a/.github/workflows/failures.yml +++ b/.github/workflows/failures.yml @@ -56,12 +56,12 @@ jobs: - name: Download artifact if: matrix.libgccjit_version.gcc != 'libgccjit12.so' - run: curl -LO https://github.com/rust-lang/gcc/releases/latest/download/gcc-13.deb + run: curl -LO https://github.com/rust-lang/gcc/releases/latest/download/gcc-15.deb - name: Setup path to libgccjit if: matrix.libgccjit_version.gcc != 'libgccjit12.so' run: | - sudo dpkg --force-overwrite -i gcc-13.deb + sudo dpkg --force-overwrite -i gcc-15.deb echo 'gcc-path = "/usr/lib"' > config.toml echo "LIBRARY_PATH=/usr/lib" >> $GITHUB_ENV echo "LD_LIBRARY_PATH=/usr/lib" >> $GITHUB_ENV diff --git a/.github/workflows/m68k.yml b/.github/workflows/m68k.yml index 07bb372b3606..369299e64478 100644 --- a/.github/workflows/m68k.yml +++ b/.github/workflows/m68k.yml @@ -47,17 +47,17 @@ jobs: - name: Install packages run: | sudo apt-get update - sudo apt-get install qemu qemu-user-static + sudo apt-get install qemu-system qemu-user-static - name: Download artifact - run: curl -LO https://github.com/cross-cg-gcc-tools/cross-gcc/releases/latest/download/gcc-m68k-13.deb + run: curl -LO https://github.com/cross-cg-gcc-tools/cross-gcc/releases/latest/download/gcc-m68k-15.deb - name: Download VM artifact run: curl -LO https://github.com/cross-cg-gcc-tools/vms/releases/latest/download/debian-m68k.img - name: Setup path to libgccjit run: | - sudo dpkg -i gcc-m68k-13.deb + sudo dpkg -i gcc-m68k-15.deb echo 'gcc-path = "/usr/lib/"' > config.toml - name: Set env diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 60e0943c87da..f36b14970482 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -37,11 +37,11 @@ jobs: run: sudo apt-get install ninja-build ripgrep - name: Download artifact - run: curl -LO https://github.com/rust-lang/gcc/releases/latest/download/gcc-13.deb + run: curl -LO https://github.com/rust-lang/gcc/releases/latest/download/gcc-15.deb - name: Setup path to libgccjit run: | - sudo dpkg --force-overwrite -i gcc-13.deb + sudo dpkg --force-overwrite -i gcc-15.deb echo 'gcc-path = "/usr/lib/"' > config.toml - name: Set env diff --git a/libgccjit.version b/libgccjit.version index ff58accec1d4..417fd5b03935 100644 --- a/libgccjit.version +++ b/libgccjit.version @@ -1 +1 @@ -45648c2edd4ecd862d9f08196d3d6c6ccba79f07 +e607be166673a8de9fc07f6f02c60426e556c5f2 From 0ab1f8ddb0d8364892e7cf2a064f9eb988c91a23 Mon Sep 17 00:00:00 2001 From: Antoni Boucher Date: Wed, 15 Jan 2025 10:30:57 -0500 Subject: [PATCH 06/81] Update the CI to Ubuntu 24.04 --- .github/workflows/ci.yml | 6 +++--- .github/workflows/failures.yml | 2 +- .github/workflows/gcc12.yml | 2 +- .github/workflows/m68k.yml | 2 +- .github/workflows/release.yml | 2 +- 5 files changed, 7 insertions(+), 7 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index fa6133c75e31..f96912e6b7a8 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -13,7 +13,7 @@ env: jobs: build: - runs-on: ubuntu-22.04 + runs-on: ubuntu-24.04 strategy: fail-fast: false @@ -108,13 +108,13 @@ jobs: cargo clippy --all-targets --features master -- -D warnings duplicates: - runs-on: ubuntu-latest + runs-on: ubuntu-24.04 steps: - uses: actions/checkout@v4 - run: python tools/check_intrinsics_duplicates.py build_system: - runs-on: ubuntu-latest + runs-on: ubuntu-24.04 steps: - uses: actions/checkout@v4 - name: Test build system diff --git a/.github/workflows/failures.yml b/.github/workflows/failures.yml index 407c9b31d05c..d080bbfe91fe 100644 --- a/.github/workflows/failures.yml +++ b/.github/workflows/failures.yml @@ -13,7 +13,7 @@ env: jobs: build: - runs-on: ubuntu-22.04 + runs-on: ubuntu-24.04 strategy: fail-fast: false diff --git a/.github/workflows/gcc12.yml b/.github/workflows/gcc12.yml index 4c2ce91e86ee..bb9e020dc6a4 100644 --- a/.github/workflows/gcc12.yml +++ b/.github/workflows/gcc12.yml @@ -17,7 +17,7 @@ env: jobs: build: - runs-on: ubuntu-22.04 + runs-on: ubuntu-24.04 strategy: fail-fast: false diff --git a/.github/workflows/m68k.yml b/.github/workflows/m68k.yml index 369299e64478..ed1fc02bd913 100644 --- a/.github/workflows/m68k.yml +++ b/.github/workflows/m68k.yml @@ -17,7 +17,7 @@ env: jobs: build: - runs-on: ubuntu-22.04 + runs-on: ubuntu-24.04 strategy: fail-fast: false diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index f36b14970482..77bb9056b279 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -13,7 +13,7 @@ env: jobs: build: - runs-on: ubuntu-22.04 + runs-on: ubuntu-24.04 strategy: fail-fast: false From 638611f5f5ab1262f42791d9e8771d29dac6cd87 Mon Sep 17 00:00:00 2001 From: Raj Aryan Agrawal Date: Thu, 16 Jan 2025 15:46:33 +0900 Subject: [PATCH 07/81] Add grep check for LTO Test --- .github/workflows/release.yml | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 77bb9056b279..886ce90b4713 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -76,4 +76,9 @@ jobs: - name: Run y.sh cargo build run: | EMBED_LTO_BITCODE=1 CHANNEL="release" ./y.sh cargo build --release --manifest-path tests/hello-world/Cargo.toml - # TODO: grep the asm output for "call my_func" and fail if it is found. + call_found=$(objdump -dj .text tests/hello-world/target/release/hello_world | grep -c "call .*mylib.*my_func" ) ||: + if [ $call_found -gt 0 ]; then + echo "ERROR: call my_func found in asm" + echo "Test is done with LTO enabled, hence inlining should occur across crates" + exit 1 + fi From e9a566002dc3ca20920baa70ba3bf59c2798819a Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Mon, 20 Jan 2025 03:29:04 +0000 Subject: [PATCH 08/81] Get rid of mir::Const::from_ty_const --- compiler/rustc_middle/src/mir/consts.rs | 11 ----- compiler/rustc_middle/src/ty/util.rs | 9 ++-- compiler/rustc_mir_transform/src/gvn.rs | 18 ++------ .../rustc_mir_transform/src/instsimplify.rs | 2 +- compiler/rustc_pattern_analysis/src/rustc.rs | 4 +- compiler/rustc_smir/src/rustc_smir/context.rs | 15 +++---- .../rustc_smir/src/rustc_smir/convert/mod.rs | 2 - .../rustc_smir/src/rustc_smir/convert/ty.rs | 42 ------------------- .../src/matches/overlapping_arms.rs | 7 +--- src/tools/clippy/clippy_utils/src/lib.rs | 9 ++-- 10 files changed, 21 insertions(+), 98 deletions(-) diff --git a/compiler/rustc_middle/src/mir/consts.rs b/compiler/rustc_middle/src/mir/consts.rs index 60e1ff1d0493..66d97fda4333 100644 --- a/compiler/rustc_middle/src/mir/consts.rs +++ b/compiler/rustc_middle/src/mir/consts.rs @@ -460,17 +460,6 @@ impl<'tcx> Const<'tcx> { Self::Val(val, ty) } - pub fn from_ty_const(c: ty::Const<'tcx>, ty: Ty<'tcx>, tcx: TyCtxt<'tcx>) -> Self { - match c.kind() { - ty::ConstKind::Value(ty, valtree) => { - // Make sure that if `c` is normalized, then the return value is normalized. - let const_val = tcx.valtree_to_const_val((ty, valtree)); - Self::Val(const_val, ty) - } - _ => Self::Ty(ty, c), - } - } - /// Return true if any evaluation of this constant always returns the same value, /// taking into account even pointer identity tests. pub fn is_deterministic(&self) -> bool { diff --git a/compiler/rustc_middle/src/ty/util.rs b/compiler/rustc_middle/src/ty/util.rs index 75893da0e583..7d5e5c2e8237 100644 --- a/compiler/rustc_middle/src/ty/util.rs +++ b/compiler/rustc_middle/src/ty/util.rs @@ -20,6 +20,7 @@ use tracing::{debug, instrument}; use super::TypingEnv; use crate::middle::codegen_fn_attrs::CodegenFnAttrFlags; +use crate::mir; use crate::query::Providers; use crate::ty::fold::fold_regions; use crate::ty::layout::{FloatExt, IntegerExt}; @@ -1183,18 +1184,18 @@ impl<'tcx> Ty<'tcx> { /// Returns the maximum value for the given numeric type (including `char`s) /// or returns `None` if the type is not numeric. - pub fn numeric_max_val(self, tcx: TyCtxt<'tcx>) -> Option> { + pub fn numeric_max_val(self, tcx: TyCtxt<'tcx>) -> Option> { let typing_env = TypingEnv::fully_monomorphized(); self.numeric_min_and_max_as_bits(tcx) - .map(|(_, max)| ty::Const::from_bits(tcx, max, typing_env, self)) + .map(|(_, max)| mir::Const::from_bits(tcx, max, typing_env, self)) } /// Returns the minimum value for the given numeric type (including `char`s) /// or returns `None` if the type is not numeric. - pub fn numeric_min_val(self, tcx: TyCtxt<'tcx>) -> Option> { + pub fn numeric_min_val(self, tcx: TyCtxt<'tcx>) -> Option> { let typing_env = TypingEnv::fully_monomorphized(); self.numeric_min_and_max_as_bits(tcx) - .map(|(min, _)| ty::Const::from_bits(tcx, min, typing_env, self)) + .map(|(min, _)| mir::Const::from_bits(tcx, min, typing_env, self)) } /// Checks whether values of this type `T` have a size known at diff --git a/compiler/rustc_mir_transform/src/gvn.rs b/compiler/rustc_mir_transform/src/gvn.rs index cb03b422d9e3..4b9a002dd3ae 100644 --- a/compiler/rustc_mir_transform/src/gvn.rs +++ b/compiler/rustc_mir_transform/src/gvn.rs @@ -1174,11 +1174,7 @@ impl<'body, 'tcx> VnState<'body, 'tcx> { ) if let ty::Slice(..) = to.builtin_deref(true).unwrap().kind() && let ty::Array(_, len) = from.builtin_deref(true).unwrap().kind() => { - return self.insert_constant(Const::from_ty_const( - *len, - self.tcx.types.usize, - self.tcx, - )); + return self.insert_constant(Const::Ty(self.tcx.types.usize, *len)); } _ => Value::UnaryOp(op, arg_index), }; @@ -1488,11 +1484,7 @@ impl<'body, 'tcx> VnState<'body, 'tcx> { // Trivial case: we are fetching a statically known length. let place_ty = place.ty(self.local_decls, self.tcx).ty; if let ty::Array(_, len) = place_ty.kind() { - return self.insert_constant(Const::from_ty_const( - *len, - self.tcx.types.usize, - self.tcx, - )); + return self.insert_constant(Const::Ty(self.tcx.types.usize, *len)); } let mut inner = self.simplify_place_value(place, location)?; @@ -1514,11 +1506,7 @@ impl<'body, 'tcx> VnState<'body, 'tcx> { && let Some(to) = to.builtin_deref(true) && let ty::Slice(..) = to.kind() { - return self.insert_constant(Const::from_ty_const( - *len, - self.tcx.types.usize, - self.tcx, - )); + return self.insert_constant(Const::Ty(self.tcx.types.usize, *len)); } // Fallback: a symbolic `Len`. diff --git a/compiler/rustc_mir_transform/src/instsimplify.rs b/compiler/rustc_mir_transform/src/instsimplify.rs index 5a36519e6a3b..9c94048d4594 100644 --- a/compiler/rustc_mir_transform/src/instsimplify.rs +++ b/compiler/rustc_mir_transform/src/instsimplify.rs @@ -167,7 +167,7 @@ impl<'tcx> InstSimplifyContext<'_, 'tcx> { if let Rvalue::Len(ref place) = *rvalue { let place_ty = place.ty(self.local_decls, self.tcx).ty; if let ty::Array(_, len) = *place_ty.kind() { - let const_ = Const::from_ty_const(len, self.tcx.types.usize, self.tcx); + let const_ = Const::Ty(self.tcx.types.usize, len); let constant = ConstOperand { span: DUMMY_SP, const_, user_ty: None }; *rvalue = Rvalue::Use(Operand::Constant(Box::new(constant))); } diff --git a/compiler/rustc_pattern_analysis/src/rustc.rs b/compiler/rustc_pattern_analysis/src/rustc.rs index ae991e3ce403..2694cf472f48 100644 --- a/compiler/rustc_pattern_analysis/src/rustc.rs +++ b/compiler/rustc_pattern_analysis/src/rustc.rs @@ -794,9 +794,7 @@ impl<'p, 'tcx: 'p> RustcPatCtxt<'p, 'tcx> { // fictitious values after `{u,i}size::MAX` (see [`IntRange::split`] for why we do // this). We show this to the user as `usize::MAX..` which is slightly incorrect but // probably clear enough. - let c = ty.numeric_max_val(cx.tcx).unwrap(); - let value = mir::Const::from_ty_const(c, ty.0, cx.tcx); - lo = PatRangeBoundary::Finite(value); + lo = PatRangeBoundary::Finite(ty.numeric_max_val(cx.tcx).unwrap()); } let hi = if let Some(hi) = range.hi.minus_one() { hi diff --git a/compiler/rustc_smir/src/rustc_smir/context.rs b/compiler/rustc_smir/src/rustc_smir/context.rs index 9793a4d41623..31c7e6c3eb44 100644 --- a/compiler/rustc_smir/src/rustc_smir/context.rs +++ b/compiler/rustc_smir/src/rustc_smir/context.rs @@ -451,16 +451,13 @@ impl<'tcx> Context for TablesWrapper<'tcx> { let ty = ty::Ty::new_static_str(tcx); let bytes = value.as_bytes(); let val_tree = ty::ValTree::from_raw_bytes(tcx, bytes); - - let ct = ty::Const::new_value(tcx, val_tree, ty); - super::convert::mir_const_from_ty_const(&mut *tables, ct, ty) + let val = tcx.valtree_to_const_val((ty, val_tree)); + mir::Const::from_value(val, ty).stable(&mut tables) } fn new_const_bool(&self, value: bool) -> MirConst { let mut tables = self.0.borrow_mut(); - let ct = ty::Const::from_bool(tables.tcx, value); - let ty = tables.tcx.types.bool; - super::convert::mir_const_from_ty_const(&mut *tables, ct, ty) + mir::Const::from_bool(tables.tcx, value).stable(&mut tables) } fn try_new_const_uint(&self, value: u128, uint_ty: UintTy) -> Result { @@ -472,13 +469,11 @@ impl<'tcx> Context for TablesWrapper<'tcx> { .layout_of(ty::TypingEnv::fully_monomorphized().as_query_input(ty)) .unwrap() .size; - - // We don't use Const::from_bits since it doesn't have any error checking. let scalar = ScalarInt::try_from_uint(value, size).ok_or_else(|| { Error::new(format!("Value overflow: cannot convert `{value}` to `{ty}`.")) })?; - let ct = ty::Const::new_value(tables.tcx, ValTree::from_scalar_int(scalar), ty); - Ok(super::convert::mir_const_from_ty_const(&mut *tables, ct, ty)) + Ok(mir::Const::from_scalar(tcx, mir::interpret::Scalar::Int(scalar), ty) + .stable(&mut tables)) } fn try_new_ty_const_uint( &self, diff --git a/compiler/rustc_smir/src/rustc_smir/convert/mod.rs b/compiler/rustc_smir/src/rustc_smir/convert/mod.rs index 4f8da08eff91..a3da563af50d 100644 --- a/compiler/rustc_smir/src/rustc_smir/convert/mod.rs +++ b/compiler/rustc_smir/src/rustc_smir/convert/mod.rs @@ -9,8 +9,6 @@ mod error; mod mir; mod ty; -pub(crate) use ty::mir_const_from_ty_const; - impl<'tcx> Stable<'tcx> for rustc_hir::Safety { type T = stable_mir::mir::Safety; fn stable(&self, _: &mut Tables<'_>) -> Self::T { diff --git a/compiler/rustc_smir/src/rustc_smir/convert/ty.rs b/compiler/rustc_smir/src/rustc_smir/convert/ty.rs index a7e122639eac..ff452eea23d2 100644 --- a/compiler/rustc_smir/src/rustc_smir/convert/ty.rs +++ b/compiler/rustc_smir/src/rustc_smir/convert/ty.rs @@ -414,48 +414,6 @@ impl<'tcx> Stable<'tcx> for ty::Pattern<'tcx> { } } -pub(crate) fn mir_const_from_ty_const<'tcx>( - tables: &mut Tables<'tcx>, - ty_const: ty::Const<'tcx>, - ty: Ty<'tcx>, -) -> stable_mir::ty::MirConst { - let kind = match ty_const.kind() { - ty::ConstKind::Value(ty, val) => { - let val = match val { - ty::ValTree::Leaf(scalar) => ty::ValTree::Leaf(scalar), - ty::ValTree::Branch(branch) => { - ty::ValTree::Branch(tables.tcx.lift(branch).unwrap()) - } - }; - let ty = tables.tcx.lift(ty).unwrap(); - let const_val = tables.tcx.valtree_to_const_val((ty, val)); - if matches!(const_val, mir::ConstValue::ZeroSized) { - stable_mir::ty::ConstantKind::ZeroSized - } else { - stable_mir::ty::ConstantKind::Allocated(alloc::new_allocation( - ty, const_val, tables, - )) - } - } - ty::ConstKind::Param(param) => stable_mir::ty::ConstantKind::Param(param.stable(tables)), - ty::ConstKind::Error(_) => unreachable!(), - ty::ConstKind::Infer(_) => unreachable!(), - ty::ConstKind::Bound(_, _) => unimplemented!(), - ty::ConstKind::Placeholder(_) => unimplemented!(), - ty::ConstKind::Unevaluated(uv) => { - stable_mir::ty::ConstantKind::Unevaluated(stable_mir::ty::UnevaluatedConst { - def: tables.const_def(uv.def), - args: uv.args.stable(tables), - promoted: None, - }) - } - ty::ConstKind::Expr(_) => unimplemented!(), - }; - let stable_ty = tables.intern_ty(ty); - let id = tables.intern_mir_const(mir::Const::Ty(ty, ty_const)); - stable_mir::ty::MirConst::new(kind, stable_ty, id) -} - impl<'tcx> Stable<'tcx> for ty::Const<'tcx> { type T = stable_mir::ty::TyConst; diff --git a/src/tools/clippy/clippy_lints/src/matches/overlapping_arms.rs b/src/tools/clippy/clippy_lints/src/matches/overlapping_arms.rs index 4a5d3c516b88..4184f8b9e6e8 100644 --- a/src/tools/clippy/clippy_lints/src/matches/overlapping_arms.rs +++ b/src/tools/clippy/clippy_lints/src/matches/overlapping_arms.rs @@ -3,7 +3,6 @@ use clippy_utils::diagnostics::span_lint_and_note; use core::cmp::Ordering; use rustc_hir::{Arm, Expr, PatKind, RangeEnd}; use rustc_lint::LateContext; -use rustc_middle::mir; use rustc_middle::ty::Ty; use rustc_span::Span; @@ -36,14 +35,12 @@ fn all_ranges<'tcx>(cx: &LateContext<'tcx>, arms: &'tcx [Arm<'_>], ty: Ty<'tcx>) let lhs_const = if let Some(lhs) = lhs { ConstEvalCtxt::new(cx).eval_pat_expr(lhs)? } else { - let min_val_const = ty.numeric_min_val(cx.tcx)?; - mir_to_const(cx.tcx, mir::Const::from_ty_const(min_val_const, ty, cx.tcx))? + mir_to_const(cx.tcx, ty.numeric_min_val(cx.tcx)?)? }; let rhs_const = if let Some(rhs) = rhs { ConstEvalCtxt::new(cx).eval_pat_expr(rhs)? } else { - let max_val_const = ty.numeric_max_val(cx.tcx)?; - mir_to_const(cx.tcx, mir::Const::from_ty_const(max_val_const, ty, cx.tcx))? + mir_to_const(cx.tcx, ty.numeric_max_val(cx.tcx)?)? }; let lhs_val = lhs_const.int_value(cx.tcx, ty)?; let rhs_val = rhs_const.int_value(cx.tcx, ty)?; diff --git a/src/tools/clippy/clippy_utils/src/lib.rs b/src/tools/clippy/clippy_utils/src/lib.rs index eecfc3fb13f8..cf0993e1f4a3 100644 --- a/src/tools/clippy/clippy_utils/src/lib.rs +++ b/src/tools/clippy/clippy_utils/src/lib.rs @@ -112,7 +112,6 @@ use rustc_hir::{ use rustc_lexer::{TokenKind, tokenize}; use rustc_lint::{LateContext, Level, Lint, LintContext}; use rustc_middle::hir::place::PlaceBase; -use rustc_middle::mir::Const; use rustc_middle::ty::adjustment::{Adjust, Adjustment, AutoBorrow}; use rustc_middle::ty::fast_reject::SimplifiedType; use rustc_middle::ty::layout::IntegerExt; @@ -1584,8 +1583,8 @@ pub fn is_range_full(cx: &LateContext<'_>, expr: &Expr<'_>, container_path: Opti let start_is_none_or_min = start.is_none_or(|start| { if let rustc_ty::Adt(_, subst) = ty.kind() && let bnd_ty = subst.type_at(0) - && let Some(min_val) = bnd_ty.numeric_min_val(cx.tcx) - && let Some(min_const) = mir_to_const(cx.tcx, Const::from_ty_const(min_val, bnd_ty, cx.tcx)) + && let Some(min_const) = bnd_ty.numeric_min_val(cx.tcx) + && let Some(min_const) = mir_to_const(cx.tcx, min_const) && let Some(start_const) = ConstEvalCtxt::new(cx).eval(start) { start_const == min_const @@ -1597,8 +1596,8 @@ pub fn is_range_full(cx: &LateContext<'_>, expr: &Expr<'_>, container_path: Opti RangeLimits::Closed => { if let rustc_ty::Adt(_, subst) = ty.kind() && let bnd_ty = subst.type_at(0) - && let Some(max_val) = bnd_ty.numeric_max_val(cx.tcx) - && let Some(max_const) = mir_to_const(cx.tcx, Const::from_ty_const(max_val, bnd_ty, cx.tcx)) + && let Some(max_const) = bnd_ty.numeric_max_val(cx.tcx) + && let Some(max_const) = mir_to_const(cx.tcx, max_const) && let Some(end_const) = ConstEvalCtxt::new(cx).eval(end) { end_const == max_const From 893d81f1e219109d098309d9e3f435b9097da47f Mon Sep 17 00:00:00 2001 From: Folkert de Vries Date: Mon, 20 Jan 2025 15:46:53 +0100 Subject: [PATCH 09/81] on s390x, use `PassMode::Direct` for vector types --- compiler/rustc_target/src/callconv/s390x.rs | 14 +- tests/codegen/s390x-simd.rs | 143 ++++++++++++++++++++ 2 files changed, 154 insertions(+), 3 deletions(-) create mode 100644 tests/codegen/s390x-simd.rs diff --git a/compiler/rustc_target/src/callconv/s390x.rs b/compiler/rustc_target/src/callconv/s390x.rs index c99eb9226eff..a73c1a0f46c2 100644 --- a/compiler/rustc_target/src/callconv/s390x.rs +++ b/compiler/rustc_target/src/callconv/s390x.rs @@ -38,9 +38,17 @@ where } let size = arg.layout.size; - if size.bits() <= 128 && arg.layout.is_single_vector_element(cx, size) { - arg.cast_to(Reg { kind: RegKind::Vector, size }); - return; + if size.bits() <= 128 { + if let BackendRepr::Vector { .. } = arg.layout.backend_repr { + // pass non-wrapped vector types using `PassMode::Direct` + return; + } + + if arg.layout.is_single_vector_element(cx, size) { + // pass non-transparant wrappers around a vector as `PassMode::Cast` + arg.cast_to(Reg { kind: RegKind::Vector, size }); + return; + } } if !arg.layout.is_aggregate() && size.bits() <= 64 { arg.extend_integer_width_to(64); diff --git a/tests/codegen/s390x-simd.rs b/tests/codegen/s390x-simd.rs new file mode 100644 index 000000000000..23181e6a1030 --- /dev/null +++ b/tests/codegen/s390x-simd.rs @@ -0,0 +1,143 @@ +//! test that s390x vector types are passed using `PassMode::Direct` +//! see also https://github.com/rust-lang/rust/issues/135744 +//@ add-core-stubs +//@ compile-flags: --target s390x-unknown-linux-gnu -O +//@ needs-llvm-components: systemz + +#![crate_type = "rlib"] +#![feature(no_core, asm_experimental_arch)] +#![feature(s390x_target_feature, simd_ffi, link_llvm_intrinsics, repr_simd)] +#![no_core] + +extern crate minicore; +use minicore::*; + +#[repr(simd)] +struct i8x16([i8; 16]); + +#[repr(simd)] +struct i16x8([i16; 8]); + +#[repr(simd)] +struct i32x4([i32; 4]); + +#[repr(simd)] +struct i64x2([i64; 2]); + +#[repr(simd)] +struct f32x4([f32; 4]); + +#[repr(simd)] +struct f64x2([f64; 2]); + +#[allow(improper_ctypes)] +extern "C" { + #[link_name = "llvm.smax.v16i8"] + fn vmxb(a: i8x16, b: i8x16) -> i8x16; + #[link_name = "llvm.smax.v8i16"] + fn vmxh(a: i16x8, b: i16x8) -> i16x8; + #[link_name = "llvm.smax.v4i32"] + fn vmxf(a: i32x4, b: i32x4) -> i32x4; + #[link_name = "llvm.smax.v2i64"] + fn vmxg(a: i64x2, b: i64x2) -> i64x2; +} + +// CHECK-LABEL: define <16 x i8> @max_i8x16 +// CHECK-SAME: <16 x i8> %a, <16 x i8> %b +// CHECK: call <16 x i8> @llvm.smax.v16i8(<16 x i8> %a, <16 x i8> %b) +#[no_mangle] +#[target_feature(enable = "vector")] +pub unsafe extern "C" fn max_i8x16(a: i8x16, b: i8x16) -> i8x16 { + vmxb(a, b) +} + +// CHECK-LABEL: define <8 x i16> @max_i16x8 +// CHECK-SAME: <8 x i16> %a, <8 x i16> %b +// CHECK: call <8 x i16> @llvm.smax.v8i16(<8 x i16> %a, <8 x i16> %b) +#[no_mangle] +#[target_feature(enable = "vector")] +pub unsafe extern "C" fn max_i16x8(a: i16x8, b: i16x8) -> i16x8 { + vmxh(a, b) +} + +// CHECK-LABEL: define <4 x i32> @max_i32x4 +// CHECK-SAME: <4 x i32> %a, <4 x i32> %b +// CHECK: call <4 x i32> @llvm.smax.v4i32(<4 x i32> %a, <4 x i32> %b) +#[no_mangle] +#[target_feature(enable = "vector")] +pub unsafe extern "C" fn max_i32x4(a: i32x4, b: i32x4) -> i32x4 { + vmxf(a, b) +} + +// CHECK-LABEL: define <2 x i64> @max_i64x2 +// CHECK-SAME: <2 x i64> %a, <2 x i64> %b +// CHECK: call <2 x i64> @llvm.smax.v2i64(<2 x i64> %a, <2 x i64> %b) +#[no_mangle] +#[target_feature(enable = "vector")] +pub unsafe extern "C" fn max_i64x2(a: i64x2, b: i64x2) -> i64x2 { + vmxg(a, b) +} + +// CHECK-LABEL: define <4 x float> @choose_f32x4 +// CHECK-SAME: <4 x float> %a, <4 x float> %b +#[no_mangle] +#[target_feature(enable = "vector")] +pub unsafe extern "C" fn choose_f32x4(a: f32x4, b: f32x4, c: bool) -> f32x4 { + if c { a } else { b } +} + +// CHECK-LABEL: define <2 x double> @choose_f64x2 +// CHECK-SAME: <2 x double> %a, <2 x double> %b +#[no_mangle] +#[target_feature(enable = "vector")] +pub unsafe extern "C" fn choose_f64x2(a: f64x2, b: f64x2, c: bool) -> f64x2 { + if c { a } else { b } +} + +#[repr(C)] +struct Wrapper(T); + +#[no_mangle] +#[inline(never)] +#[target_feature(enable = "vector")] +pub unsafe extern "C" fn max_wrapper_i8x16(a: Wrapper, b: Wrapper) -> Wrapper { + // CHECK-LABEL: max_wrapper_i8x16 + // CHECK-SAME: sret([16 x i8]) + // CHECK-SAME: <16 x i8> + // CHECK-SAME: <16 x i8> + // CHECK: call <16 x i8> @llvm.smax.v16i8 + // CHECK-SAME: <16 x i8> + // CHECK-SAME: <16 x i8> + Wrapper(vmxb(a.0, b.0)) +} + +#[no_mangle] +#[inline(never)] +#[target_feature(enable = "vector")] +pub unsafe extern "C" fn max_wrapper_i64x2(a: Wrapper, b: Wrapper) -> Wrapper { + // CHECK-LABEL: max_wrapper_i64x2 + // CHECK-SAME: sret([16 x i8]) + // CHECK-SAME: <16 x i8> + // CHECK-SAME: <16 x i8> + // CHECK: call <2 x i64> @llvm.smax.v2i64 + // CHECK-SAME: <2 x i64> + // CHECK-SAME: <2 x i64> + Wrapper(vmxg(a.0, b.0)) +} + +#[no_mangle] +#[inline(never)] +#[target_feature(enable = "vector")] +pub unsafe extern "C" fn choose_wrapper_f64x2( + a: Wrapper, + b: Wrapper, + c: bool, +) -> Wrapper { + // CHECK-LABEL: choose_wrapper_f64x2 + // CHECK-SAME: sret([16 x i8]) + // CHECK-SAME: <16 x i8> + // CHECK-SAME: <16 x i8> + Wrapper(choose_f64x2(a.0, b.0, c)) +} + +// CHECK: declare <2 x i64> @llvm.smax.v2i64(<2 x i64>, <2 x i64>) From a9495e01187a8aadb4500993d40ce7b27e1958d2 Mon Sep 17 00:00:00 2001 From: Walnut <39544927+Walnut356@users.noreply.github.com> Date: Tue, 21 Jan 2025 03:23:01 -0600 Subject: [PATCH 10/81] change lookup from `OsString.inner.inner.0` -> `OsString.inner.inner.bytes` --- src/etc/gdb_providers.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/etc/gdb_providers.py b/src/etc/gdb_providers.py index 34bb5c39909e..c8f4a32cb17e 100644 --- a/src/etc/gdb_providers.py +++ b/src/etc/gdb_providers.py @@ -71,7 +71,7 @@ class StdOsStringProvider(printer_base): self._valobj = valobj buf = self._valobj["inner"]["inner"] is_windows = "Wtf8Buf" in buf.type.name - vec = buf[ZERO_FIELD] if is_windows else buf + vec = buf["bytes"] if is_windows else buf self._length = int(vec["len"]) self._data_ptr = unwrap_unique_or_non_null(vec["buf"]["inner"]["ptr"]) From 0d90d47fb3b5761bd46fcd35d8dba7fd661e3ca2 Mon Sep 17 00:00:00 2001 From: Chris Krycho Date: Tue, 21 Jan 2025 13:51:21 -0700 Subject: [PATCH 11/81] TRPL: more backward-compatible Edition changes - Improve the discussion of `unsafe` blocks within `unsafe` functions. - Fix formatting in Appendix A --- src/doc/book | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/doc/book b/src/doc/book index 8a0eee28f769..8c95f8cc4383 160000 --- a/src/doc/book +++ b/src/doc/book @@ -1 +1 @@ -Subproject commit 8a0eee28f769387e543882352b12d956aa1b7c38 +Subproject commit 8c95f8cc4383c819cb552e651e932612fd4027b2 From 9cfc4205d334e9e80bbd042f04a7c849a4262b2a Mon Sep 17 00:00:00 2001 From: Chris Krycho Date: Tue, 21 Jan 2025 16:00:20 -0700 Subject: [PATCH 12/81] TRPL: integrate edits to Chapter 17 --- src/doc/book | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/doc/book b/src/doc/book index 8c95f8cc4383..82a4a49789bc 160000 --- a/src/doc/book +++ b/src/doc/book @@ -1 +1 @@ -Subproject commit 8c95f8cc4383c819cb552e651e932612fd4027b2 +Subproject commit 82a4a49789bc96db1a1b2a210b4c5ed7c9ef0c0d From aaccb71da9f0954ee5433f61ae8274b29f6da1c5 Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Mon, 20 Jan 2025 11:38:48 +0100 Subject: [PATCH 13/81] Fix sparcv8plus test on LLVM 20 Split this into two tests, one for LLVM 19 and one for LLVM 20. --- tests/ui/abi/sparcv8plus-llvm19.rs | 43 +++++++++++++++++++ tests/ui/abi/sparcv8plus-llvm19.sparc.stderr | 8 ++++ .../sparcv8plus-llvm19.sparc_cpu_v9.stderr | 8 ++++ ...-llvm19.sparc_cpu_v9_feature_v8plus.stderr | 8 ++++ ...cv8plus-llvm19.sparc_feature_v8plus.stderr | 8 ++++ .../abi/sparcv8plus-llvm19.sparcv8plus.stderr | 8 ++++ tests/ui/abi/sparcv8plus.rs | 6 +-- tests/ui/abi/sparcv8plus.sparc_cpu_v9.stderr | 6 +-- ...cv8plus.sparc_cpu_v9_feature_v8plus.stderr | 2 +- .../sparcv8plus.sparc_feature_v8plus.stderr | 2 +- tests/ui/abi/sparcv8plus.sparcv8plus.stderr | 2 +- 11 files changed, 92 insertions(+), 9 deletions(-) create mode 100644 tests/ui/abi/sparcv8plus-llvm19.rs create mode 100644 tests/ui/abi/sparcv8plus-llvm19.sparc.stderr create mode 100644 tests/ui/abi/sparcv8plus-llvm19.sparc_cpu_v9.stderr create mode 100644 tests/ui/abi/sparcv8plus-llvm19.sparc_cpu_v9_feature_v8plus.stderr create mode 100644 tests/ui/abi/sparcv8plus-llvm19.sparc_feature_v8plus.stderr create mode 100644 tests/ui/abi/sparcv8plus-llvm19.sparcv8plus.stderr diff --git a/tests/ui/abi/sparcv8plus-llvm19.rs b/tests/ui/abi/sparcv8plus-llvm19.rs new file mode 100644 index 000000000000..a884e5ca06f1 --- /dev/null +++ b/tests/ui/abi/sparcv8plus-llvm19.rs @@ -0,0 +1,43 @@ +//@ revisions: sparc sparcv8plus sparc_cpu_v9 sparc_feature_v8plus sparc_cpu_v9_feature_v8plus +//@[sparc] compile-flags: --target sparc-unknown-none-elf +//@[sparc] needs-llvm-components: sparc +//@[sparcv8plus] compile-flags: --target sparc-unknown-linux-gnu +//@[sparcv8plus] needs-llvm-components: sparc +//@[sparc_cpu_v9] compile-flags: --target sparc-unknown-none-elf -C target-cpu=v9 +//@[sparc_cpu_v9] needs-llvm-components: sparc +//@[sparc_feature_v8plus] compile-flags: --target sparc-unknown-none-elf -C target-feature=+v8plus +//@[sparc_feature_v8plus] needs-llvm-components: sparc +//@[sparc_cpu_v9_feature_v8plus] compile-flags: --target sparc-unknown-none-elf -C target-cpu=v9 -C target-feature=+v8plus +//@[sparc_cpu_v9_feature_v8plus] needs-llvm-components: sparc +//@ exact-llvm-major-version: 19 + +#![crate_type = "rlib"] +#![feature(no_core, rustc_attrs, lang_items)] +#![no_core] + +#[lang = "sized"] +trait Sized {} +#[lang = "copy"] +trait Copy {} + +#[rustc_builtin_macro] +macro_rules! compile_error { + () => {}; +} + +#[cfg(all(not(target_feature = "v8plus"), not(target_feature = "v9")))] +compile_error!("-v8plus,-v9"); +//[sparc]~^ ERROR -v8plus,-v9 + +// FIXME: sparc_cpu_v9 should be in "-v8plus,+v9" group (fixed in LLVM 20) +#[cfg(all(target_feature = "v8plus", target_feature = "v9"))] +compile_error!("+v8plus,+v9"); +//[sparcv8plus,sparc_cpu_v9_feature_v8plus,sparc_cpu_v9]~^ ERROR +v8plus,+v9 + +// FIXME: should be rejected +#[cfg(all(target_feature = "v8plus", not(target_feature = "v9")))] +compile_error!("+v8plus,-v9 (FIXME)"); +//[sparc_feature_v8plus]~^ ERROR +v8plus,-v9 (FIXME) + +#[cfg(all(not(target_feature = "v8plus"), target_feature = "v9"))] +compile_error!("-v8plus,+v9"); diff --git a/tests/ui/abi/sparcv8plus-llvm19.sparc.stderr b/tests/ui/abi/sparcv8plus-llvm19.sparc.stderr new file mode 100644 index 000000000000..7eedf26135f5 --- /dev/null +++ b/tests/ui/abi/sparcv8plus-llvm19.sparc.stderr @@ -0,0 +1,8 @@ +error: -v8plus,-v9 + --> $DIR/sparcv8plus-llvm19.rs:29:1 + | +LL | compile_error!("-v8plus,-v9"); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 1 previous error + diff --git a/tests/ui/abi/sparcv8plus-llvm19.sparc_cpu_v9.stderr b/tests/ui/abi/sparcv8plus-llvm19.sparc_cpu_v9.stderr new file mode 100644 index 000000000000..ac61df356780 --- /dev/null +++ b/tests/ui/abi/sparcv8plus-llvm19.sparc_cpu_v9.stderr @@ -0,0 +1,8 @@ +error: +v8plus,+v9 + --> $DIR/sparcv8plus-llvm19.rs:34:1 + | +LL | compile_error!("+v8plus,+v9"); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 1 previous error + diff --git a/tests/ui/abi/sparcv8plus-llvm19.sparc_cpu_v9_feature_v8plus.stderr b/tests/ui/abi/sparcv8plus-llvm19.sparc_cpu_v9_feature_v8plus.stderr new file mode 100644 index 000000000000..ac61df356780 --- /dev/null +++ b/tests/ui/abi/sparcv8plus-llvm19.sparc_cpu_v9_feature_v8plus.stderr @@ -0,0 +1,8 @@ +error: +v8plus,+v9 + --> $DIR/sparcv8plus-llvm19.rs:34:1 + | +LL | compile_error!("+v8plus,+v9"); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 1 previous error + diff --git a/tests/ui/abi/sparcv8plus-llvm19.sparc_feature_v8plus.stderr b/tests/ui/abi/sparcv8plus-llvm19.sparc_feature_v8plus.stderr new file mode 100644 index 000000000000..1bf7a3ad76a8 --- /dev/null +++ b/tests/ui/abi/sparcv8plus-llvm19.sparc_feature_v8plus.stderr @@ -0,0 +1,8 @@ +error: +v8plus,-v9 (FIXME) + --> $DIR/sparcv8plus-llvm19.rs:39:1 + | +LL | compile_error!("+v8plus,-v9 (FIXME)"); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 1 previous error + diff --git a/tests/ui/abi/sparcv8plus-llvm19.sparcv8plus.stderr b/tests/ui/abi/sparcv8plus-llvm19.sparcv8plus.stderr new file mode 100644 index 000000000000..ac61df356780 --- /dev/null +++ b/tests/ui/abi/sparcv8plus-llvm19.sparcv8plus.stderr @@ -0,0 +1,8 @@ +error: +v8plus,+v9 + --> $DIR/sparcv8plus-llvm19.rs:34:1 + | +LL | compile_error!("+v8plus,+v9"); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 1 previous error + diff --git a/tests/ui/abi/sparcv8plus.rs b/tests/ui/abi/sparcv8plus.rs index 108279b34949..a78ae0cd3288 100644 --- a/tests/ui/abi/sparcv8plus.rs +++ b/tests/ui/abi/sparcv8plus.rs @@ -9,7 +9,7 @@ //@[sparc_feature_v8plus] needs-llvm-components: sparc //@[sparc_cpu_v9_feature_v8plus] compile-flags: --target sparc-unknown-none-elf -C target-cpu=v9 -C target-feature=+v8plus //@[sparc_cpu_v9_feature_v8plus] needs-llvm-components: sparc -//@ min-llvm-version: 19 +//@ min-llvm-version: 20 #![crate_type = "rlib"] #![feature(no_core, rustc_attrs, lang_items)] @@ -29,10 +29,9 @@ macro_rules! compile_error { compile_error!("-v8plus,-v9"); //[sparc]~^ ERROR -v8plus,-v9 -// FIXME: sparc_cpu_v9 should be in "-v8plus,+v9" group (fixed in LLVM 20) #[cfg(all(target_feature = "v8plus", target_feature = "v9"))] compile_error!("+v8plus,+v9"); -//[sparcv8plus,sparc_cpu_v9_feature_v8plus,sparc_cpu_v9]~^ ERROR +v8plus,+v9 +//[sparcv8plus,sparc_cpu_v9_feature_v8plus]~^ ERROR +v8plus,+v9 // FIXME: should be rejected #[cfg(all(target_feature = "v8plus", not(target_feature = "v9")))] @@ -41,3 +40,4 @@ compile_error!("+v8plus,-v9 (FIXME)"); #[cfg(all(not(target_feature = "v8plus"), target_feature = "v9"))] compile_error!("-v8plus,+v9"); +//[sparc_cpu_v9]~^ ERROR -v8plus,+v9 diff --git a/tests/ui/abi/sparcv8plus.sparc_cpu_v9.stderr b/tests/ui/abi/sparcv8plus.sparc_cpu_v9.stderr index 5e1e1fa5c798..00fd7ef4ea8f 100644 --- a/tests/ui/abi/sparcv8plus.sparc_cpu_v9.stderr +++ b/tests/ui/abi/sparcv8plus.sparc_cpu_v9.stderr @@ -1,7 +1,7 @@ -error: +v8plus,+v9 - --> $DIR/sparcv8plus.rs:34:1 +error: -v8plus,+v9 + --> $DIR/sparcv8plus.rs:42:1 | -LL | compile_error!("+v8plus,+v9"); +LL | compile_error!("-v8plus,+v9"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: aborting due to 1 previous error diff --git a/tests/ui/abi/sparcv8plus.sparc_cpu_v9_feature_v8plus.stderr b/tests/ui/abi/sparcv8plus.sparc_cpu_v9_feature_v8plus.stderr index 5e1e1fa5c798..a3c74e67f8f1 100644 --- a/tests/ui/abi/sparcv8plus.sparc_cpu_v9_feature_v8plus.stderr +++ b/tests/ui/abi/sparcv8plus.sparc_cpu_v9_feature_v8plus.stderr @@ -1,5 +1,5 @@ error: +v8plus,+v9 - --> $DIR/sparcv8plus.rs:34:1 + --> $DIR/sparcv8plus.rs:33:1 | LL | compile_error!("+v8plus,+v9"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/abi/sparcv8plus.sparc_feature_v8plus.stderr b/tests/ui/abi/sparcv8plus.sparc_feature_v8plus.stderr index 8a5375a46bc0..84f560d158ca 100644 --- a/tests/ui/abi/sparcv8plus.sparc_feature_v8plus.stderr +++ b/tests/ui/abi/sparcv8plus.sparc_feature_v8plus.stderr @@ -1,5 +1,5 @@ error: +v8plus,-v9 (FIXME) - --> $DIR/sparcv8plus.rs:39:1 + --> $DIR/sparcv8plus.rs:38:1 | LL | compile_error!("+v8plus,-v9 (FIXME)"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/abi/sparcv8plus.sparcv8plus.stderr b/tests/ui/abi/sparcv8plus.sparcv8plus.stderr index 5e1e1fa5c798..a3c74e67f8f1 100644 --- a/tests/ui/abi/sparcv8plus.sparcv8plus.stderr +++ b/tests/ui/abi/sparcv8plus.sparcv8plus.stderr @@ -1,5 +1,5 @@ error: +v8plus,+v9 - --> $DIR/sparcv8plus.rs:34:1 + --> $DIR/sparcv8plus.rs:33:1 | LL | compile_error!("+v8plus,+v9"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ From 2718710d4a505019c46ccc7db42d890f230de25e Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Mon, 20 Jan 2025 12:08:27 +0100 Subject: [PATCH 14/81] Fix x86_64-bigint-helpers test on LLVM 20 LLVM 20 choses a different unroll factor for the loop. --- tests/assembly/x86_64-bigint-helpers.rs | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/tests/assembly/x86_64-bigint-helpers.rs b/tests/assembly/x86_64-bigint-helpers.rs index 198e55435390..3ad253a2bd0f 100644 --- a/tests/assembly/x86_64-bigint-helpers.rs +++ b/tests/assembly/x86_64-bigint-helpers.rs @@ -2,6 +2,9 @@ //@ assembly-output: emit-asm //@ compile-flags: --crate-type=lib -O -C target-cpu=x86-64-v4 //@ compile-flags: -C llvm-args=-x86-asm-syntax=intel +//@ revisions: llvm-pre-20 llvm-20 +//@ [llvm-20] min-llvm-version: 20 +//@ [llvm-pre-20] max-llvm-major-version: 19 #![no_std] #![feature(bigint_helper_methods)] @@ -20,12 +23,16 @@ pub unsafe extern "sysv64" fn bigint_chain_carrying_add( n: usize, mut carry: bool, ) -> bool { - // CHECK: mov [[TEMP:r..]], qword ptr [rsi + 8*[[IND:r..]] + 8] - // CHECK: adc [[TEMP]], qword ptr [rdx + 8*[[IND]] + 8] - // CHECK: mov qword ptr [rdi + 8*[[IND]] + 8], [[TEMP]] - // CHECK: mov [[TEMP]], qword ptr [rsi + 8*[[IND]] + 16] - // CHECK: adc [[TEMP]], qword ptr [rdx + 8*[[IND]] + 16] - // CHECK: mov qword ptr [rdi + 8*[[IND]] + 16], [[TEMP]] + // llvm-pre-20: mov [[TEMP:r..]], qword ptr [rsi + 8*[[IND:r..]] + 8] + // llvm-pre-20: adc [[TEMP]], qword ptr [rdx + 8*[[IND]] + 8] + // llvm-pre-20: mov qword ptr [rdi + 8*[[IND]] + 8], [[TEMP]] + // llvm-pre-20: mov [[TEMP]], qword ptr [rsi + 8*[[IND]] + 16] + // llvm-pre-20: adc [[TEMP]], qword ptr [rdx + 8*[[IND]] + 16] + // llvm-pre-20: mov qword ptr [rdi + 8*[[IND]] + 16], [[TEMP]] + // llvm-20: adc [[TEMP:r..]], qword ptr [rdx + 8*[[IND:r..]]] + // llvm-20: mov qword ptr [rdi + 8*[[IND]]], [[TEMP]] + // llvm-20: mov [[TEMP]], qword ptr [rsi + 8*[[IND]] + 8] + // llvm-20: adc [[TEMP]], qword ptr [rdx + 8*[[IND]] + 8] for i in 0..n { (*dest.add(i), carry) = u64::carrying_add(*src1.add(i), *src2.add(i), carry); } From 4d1c16c09c75b6e44a295fc40ad11bb6ec95dec7 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Fri, 6 Dec 2024 08:52:05 +0000 Subject: [PATCH 15/81] Make the wasm_c_abi future compat warning a hard error This is the next step in getting rid of the broken C abi for wasm32-unknown-unknown. --- compiler/rustc_lint/messages.ftl | 3 -- compiler/rustc_lint/src/early/diagnostics.rs | 1 - compiler/rustc_lint/src/lints.rs | 4 -- compiler/rustc_lint_defs/src/builtin.rs | 39 -------------------- compiler/rustc_lint_defs/src/lib.rs | 1 - compiler/rustc_metadata/messages.ftl | 3 ++ compiler/rustc_metadata/src/creader.rs | 7 +--- compiler/rustc_metadata/src/errors.rs | 7 ++++ 8 files changed, 11 insertions(+), 54 deletions(-) diff --git a/compiler/rustc_lint/messages.ftl b/compiler/rustc_lint/messages.ftl index 14f0787de3ed..551e7176f77e 100644 --- a/compiler/rustc_lint/messages.ftl +++ b/compiler/rustc_lint/messages.ftl @@ -974,6 +974,3 @@ lint_use_let_underscore_ignore_suggestion = use `let _ = ...` to ignore the expr lint_variant_size_differences = enum variant is more than three times larger ({$largest} bytes) than the next largest - -lint_wasm_c_abi = - older versions of the `wasm-bindgen` crate will be incompatible with future versions of Rust; please update to `wasm-bindgen` v0.2.88 diff --git a/compiler/rustc_lint/src/early/diagnostics.rs b/compiler/rustc_lint/src/early/diagnostics.rs index 6d73715562b2..92dbc76a7b5e 100644 --- a/compiler/rustc_lint/src/early/diagnostics.rs +++ b/compiler/rustc_lint/src/early/diagnostics.rs @@ -430,7 +430,6 @@ pub(super) fn decorate_lint( BuiltinLintDiag::UnusedCrateDependency { extern_crate, local_crate } => { lints::UnusedCrateDependency { extern_crate, local_crate }.decorate_lint(diag) } - BuiltinLintDiag::WasmCAbi => lints::WasmCAbi.decorate_lint(diag), BuiltinLintDiag::IllFormedAttributeInput { suggestions } => { lints::IllFormedAttributeInput { num_suggestions: suggestions.len(), diff --git a/compiler/rustc_lint/src/lints.rs b/compiler/rustc_lint/src/lints.rs index fea3d67ffeb7..47f42d7dc621 100644 --- a/compiler/rustc_lint/src/lints.rs +++ b/compiler/rustc_lint/src/lints.rs @@ -2561,10 +2561,6 @@ pub(crate) struct UnusedCrateDependency { pub local_crate: Symbol, } -#[derive(LintDiagnostic)] -#[diag(lint_wasm_c_abi)] -pub(crate) struct WasmCAbi; - #[derive(LintDiagnostic)] #[diag(lint_ill_formed_attribute_input)] pub(crate) struct IllFormedAttributeInput { diff --git a/compiler/rustc_lint_defs/src/builtin.rs b/compiler/rustc_lint_defs/src/builtin.rs index 9fc527a6a3ab..aba28c9b7ef0 100644 --- a/compiler/rustc_lint_defs/src/builtin.rs +++ b/compiler/rustc_lint_defs/src/builtin.rs @@ -143,7 +143,6 @@ declare_lint_pass! { UNUSED_VARIABLES, USELESS_DEPRECATED, WARNINGS, - WASM_C_ABI, // tidy-alphabetical-end ] } @@ -4647,44 +4646,6 @@ declare_lint! { }; } -declare_lint! { - /// The `wasm_c_abi` lint detects crate dependencies that are incompatible - /// with future versions of Rust that will emit spec-compliant C ABI. - /// - /// ### Example - /// - /// ```rust,ignore (needs extern crate) - /// #![deny(wasm_c_abi)] - /// ``` - /// - /// This will produce: - /// - /// ```text - /// error: the following packages contain code that will be rejected by a future version of Rust: wasm-bindgen v0.2.87 - /// | - /// note: the lint level is defined here - /// --> src/lib.rs:1:9 - /// | - /// 1 | #![deny(wasm_c_abi)] - /// | ^^^^^^^^^^ - /// ``` - /// - /// ### Explanation - /// - /// Rust has historically emitted non-spec-compliant C ABI. This has caused - /// incompatibilities between other compilers and Wasm targets. In a future - /// version of Rust this will be fixed and therefore dependencies relying - /// on the non-spec-compliant C ABI will stop functioning. - pub WASM_C_ABI, - Deny, - "detects dependencies that are incompatible with the Wasm C ABI", - @future_incompatible = FutureIncompatibleInfo { - reason: FutureIncompatibilityReason::FutureReleaseErrorReportInDeps, - reference: "issue #71871 ", - }; - crate_level_only -} - declare_lint! { /// The `uncovered_param_in_projection` lint detects a violation of one of Rust's orphan rules for /// foreign trait implementations that concerns the use of type parameters inside trait associated diff --git a/compiler/rustc_lint_defs/src/lib.rs b/compiler/rustc_lint_defs/src/lib.rs index 7786d3eb59af..2956fc212533 100644 --- a/compiler/rustc_lint_defs/src/lib.rs +++ b/compiler/rustc_lint_defs/src/lib.rs @@ -783,7 +783,6 @@ pub enum BuiltinLintDiag { extern_crate: Symbol, local_crate: Symbol, }, - WasmCAbi, IllFormedAttributeInput { suggestions: Vec, }, diff --git a/compiler/rustc_metadata/messages.ftl b/compiler/rustc_metadata/messages.ftl index 6d7d88fa8d7a..d2b5ae531859 100644 --- a/compiler/rustc_metadata/messages.ftl +++ b/compiler/rustc_metadata/messages.ftl @@ -290,6 +290,9 @@ metadata_unsupported_abi = metadata_unsupported_abi_i686 = ABI not supported by `#[link(kind = "raw-dylib")]` on i686 +metadata_wasm_c_abi = + older versions of the `wasm-bindgen` crate are incompatible with current versions of Rust; please update to `wasm-bindgen` v0.2.88 + metadata_wasm_import_form = wasm import module must be of the form `wasm_import_module = "string"` diff --git a/compiler/rustc_metadata/src/creader.rs b/compiler/rustc_metadata/src/creader.rs index a6db12f89325..a6cd0ecafd0d 100644 --- a/compiler/rustc_metadata/src/creader.rs +++ b/compiler/rustc_metadata/src/creader.rs @@ -1076,12 +1076,7 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> { // Make a point span rather than covering the whole file let span = krate.spans.inner_span.shrink_to_lo(); - self.sess.psess.buffer_lint( - lint::builtin::WASM_C_ABI, - span, - ast::CRATE_NODE_ID, - BuiltinLintDiag::WasmCAbi, - ); + self.sess.dcx().emit_err(errors::WasmCAbi { span }); } } diff --git a/compiler/rustc_metadata/src/errors.rs b/compiler/rustc_metadata/src/errors.rs index b6c5619ec18a..cefc6498f68f 100644 --- a/compiler/rustc_metadata/src/errors.rs +++ b/compiler/rustc_metadata/src/errors.rs @@ -732,3 +732,10 @@ pub struct ImportNameTypeRaw { #[primary_span] pub span: Span, } + +#[derive(Diagnostic)] +#[diag(metadata_wasm_c_abi)] +pub(crate) struct WasmCAbi { + #[primary_span] + pub span: Span, +} From 49c3aaabaaf383da35d5544817feb54d1800832c Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Thu, 9 Jan 2025 09:59:04 +0000 Subject: [PATCH 16/81] Add test Co-Authored-By: Alex Crichton --- tests/ui/wasm/wasm-bindgen-broken-error.rs | 28 +++++++++++++++++++ .../wasm-bindgen-broken-error.v0_1_0.stderr | 8 ++++++ .../wasm-bindgen-broken-error.v0_2_87.stderr | 8 ++++++ 3 files changed, 44 insertions(+) create mode 100644 tests/ui/wasm/wasm-bindgen-broken-error.rs create mode 100644 tests/ui/wasm/wasm-bindgen-broken-error.v0_1_0.stderr create mode 100644 tests/ui/wasm/wasm-bindgen-broken-error.v0_2_87.stderr diff --git a/tests/ui/wasm/wasm-bindgen-broken-error.rs b/tests/ui/wasm/wasm-bindgen-broken-error.rs new file mode 100644 index 000000000000..d985e8798031 --- /dev/null +++ b/tests/ui/wasm/wasm-bindgen-broken-error.rs @@ -0,0 +1,28 @@ +//@ only-wasm32 +//@ revisions: v0_1_0 v0_2_87 v0_2_88 v0_3_0 v1_0_0 +//@[v0_1_0] check-fail +//@[v0_1_0] rustc-env:CARGO_PKG_VERSION_MAJOR=0 +//@[v0_1_0] rustc-env:CARGO_PKG_VERSION_MINOR=1 +//@[v0_1_0] rustc-env:CARGO_PKG_VERSION_PATCH=0 +//@[v0_2_87] check-fail +//@[v0_2_87] rustc-env:CARGO_PKG_VERSION_MAJOR=0 +//@[v0_2_87] rustc-env:CARGO_PKG_VERSION_MINOR=2 +//@[v0_2_87] rustc-env:CARGO_PKG_VERSION_PATCH=87 +//@[v0_2_88] check-pass +//@[v0_2_88] rustc-env:CARGO_PKG_VERSION_MAJOR=0 +//@[v0_2_88] rustc-env:CARGO_PKG_VERSION_MINOR=2 +//@[v0_2_88] rustc-env:CARGO_PKG_VERSION_PATCH=88 +//@[v0_3_0] check-pass +//@[v0_3_0] rustc-env:CARGO_PKG_VERSION_MAJOR=0 +//@[v0_3_0] rustc-env:CARGO_PKG_VERSION_MINOR=3 +//@[v0_3_0] rustc-env:CARGO_PKG_VERSION_PATCH=0 +//@[v1_0_0] check-pass +//@[v1_0_0] rustc-env:CARGO_PKG_VERSION_MAJOR=1 +//@[v1_0_0] rustc-env:CARGO_PKG_VERSION_MINOR=0 +//@[v1_0_0] rustc-env:CARGO_PKG_VERSION_PATCH=0 + +#![crate_name = "wasm_bindgen"] +//[v0_1_0]~^ ERROR: older versions of the `wasm-bindgen` crate +//[v0_2_87]~^^ ERROR: older versions of the `wasm-bindgen` crate + +fn main() {} diff --git a/tests/ui/wasm/wasm-bindgen-broken-error.v0_1_0.stderr b/tests/ui/wasm/wasm-bindgen-broken-error.v0_1_0.stderr new file mode 100644 index 000000000000..e1c1ec7ef339 --- /dev/null +++ b/tests/ui/wasm/wasm-bindgen-broken-error.v0_1_0.stderr @@ -0,0 +1,8 @@ +error: older versions of the `wasm-bindgen` crate are incompatible with current versions of Rust; please update to `wasm-bindgen` v0.2.88 + --> $DIR/wasm-bindgen-broken-error.rs:24:1 + | +LL | #![crate_name = "wasm_bindgen"] + | ^ + +error: aborting due to 1 previous error + diff --git a/tests/ui/wasm/wasm-bindgen-broken-error.v0_2_87.stderr b/tests/ui/wasm/wasm-bindgen-broken-error.v0_2_87.stderr new file mode 100644 index 000000000000..e1c1ec7ef339 --- /dev/null +++ b/tests/ui/wasm/wasm-bindgen-broken-error.v0_2_87.stderr @@ -0,0 +1,8 @@ +error: older versions of the `wasm-bindgen` crate are incompatible with current versions of Rust; please update to `wasm-bindgen` v0.2.88 + --> $DIR/wasm-bindgen-broken-error.rs:24:1 + | +LL | #![crate_name = "wasm_bindgen"] + | ^ + +error: aborting due to 1 previous error + From d0a70d93282adb3d3a0adb9b17ead93b35639c46 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Thu, 23 Jan 2025 19:01:47 +0000 Subject: [PATCH 17/81] Fix testing of the standard library with Emscripten This does need EMCC_CFLAGS="-s MAXIMUM_MEMORY=2GB" avoid several OOMs. --- library/alloc/benches/btree/map.rs | 1 + library/alloc/benches/slice.rs | 11 +++++++++++ library/alloc/benches/vec.rs | 5 +++++ library/alloc/tests/sort/tests.rs | 9 ++++++++- library/alloc/tests/sync.rs | 1 + library/std/src/io/copy/tests.rs | 1 + library/std/tests/pipe_subprocess.rs | 2 +- library/std/tests/process_spawning.rs | 3 ++- 8 files changed, 30 insertions(+), 3 deletions(-) diff --git a/library/alloc/benches/btree/map.rs b/library/alloc/benches/btree/map.rs index b8119c9f0ebf..5b15aaeddbc4 100644 --- a/library/alloc/benches/btree/map.rs +++ b/library/alloc/benches/btree/map.rs @@ -353,6 +353,7 @@ pub fn iter_10k(b: &mut Bencher) { } #[bench] +#[cfg_attr(target_os = "emscripten", ignore)] // hits an OOM pub fn iter_1m(b: &mut Bencher) { bench_iter(b, 1_000, 1_000_000); } diff --git a/library/alloc/benches/slice.rs b/library/alloc/benches/slice.rs index 48c74c4491dc..c45c37227129 100644 --- a/library/alloc/benches/slice.rs +++ b/library/alloc/benches/slice.rs @@ -366,14 +366,25 @@ rotate!(rotate_medium_half, gen_random, 9158, 9158 / 2); rotate!(rotate_medium_half_plus_one, gen_random, 9158, 9158 / 2 + 1); // Intended to use more RAM than the machine has cache +#[cfg(not(target_os = "emscripten"))] // hits an OOM rotate!(rotate_huge_by1, gen_random, 5 * 1024 * 1024, 1); +#[cfg(not(target_os = "emscripten"))] // hits an OOM rotate!(rotate_huge_by9199_u64, gen_random, 5 * 1024 * 1024, 9199); +#[cfg(not(target_os = "emscripten"))] // hits an OOM rotate!(rotate_huge_by9199_bytes, gen_random_bytes, 5 * 1024 * 1024, 9199); +#[cfg(not(target_os = "emscripten"))] // hits an OOM rotate!(rotate_huge_by9199_strings, gen_strings, 5 * 1024 * 1024, 9199); +#[cfg(not(target_os = "emscripten"))] // hits an OOM rotate!(rotate_huge_by9199_big, gen_big_random, 5 * 1024 * 1024, 9199); +#[cfg(not(target_os = "emscripten"))] // hits an OOM rotate!(rotate_huge_by1234577_u64, gen_random, 5 * 1024 * 1024, 1234577); +#[cfg(not(target_os = "emscripten"))] // hits an OOM rotate!(rotate_huge_by1234577_bytes, gen_random_bytes, 5 * 1024 * 1024, 1234577); +#[cfg(not(target_os = "emscripten"))] // hits an OOM rotate!(rotate_huge_by1234577_strings, gen_strings, 5 * 1024 * 1024, 1234577); +#[cfg(not(target_os = "emscripten"))] // hits an OOM rotate!(rotate_huge_by1234577_big, gen_big_random, 5 * 1024 * 1024, 1234577); +#[cfg(not(target_os = "emscripten"))] // hits an OOM rotate!(rotate_huge_half, gen_random, 5 * 1024 * 1024, 5 * 1024 * 1024 / 2); +#[cfg(not(target_os = "emscripten"))] // hits an OOM rotate!(rotate_huge_half_plus_one, gen_random, 5 * 1024 * 1024, 5 * 1024 * 1024 / 2 + 1); diff --git a/library/alloc/benches/vec.rs b/library/alloc/benches/vec.rs index d29ffae9d70b..a725ad6894b9 100644 --- a/library/alloc/benches/vec.rs +++ b/library/alloc/benches/vec.rs @@ -547,6 +547,11 @@ fn bench_in_place_collect_droppable(b: &mut Bencher) { }) } +// node.js gives out of memory error to use with length 1_100_000 +#[cfg(target_os = "emscripten")] +const LEN: usize = 4096; + +#[cfg(not(target_os = "emscripten"))] const LEN: usize = 16384; #[bench] diff --git a/library/alloc/tests/sort/tests.rs b/library/alloc/tests/sort/tests.rs index 4cc79010e8fe..d321f8df5189 100644 --- a/library/alloc/tests/sort/tests.rs +++ b/library/alloc/tests/sort/tests.rs @@ -11,7 +11,14 @@ use crate::sort::{Sort, known_good_stable_sort, patterns}; #[cfg(miri)] const TEST_LENGTHS: &[usize] = &[2, 3, 4, 7, 10, 15, 20, 24, 33, 50, 100, 171, 300]; -#[cfg(not(miri))] +// node.js gives out of memory error to use with length 1_100_000 +#[cfg(all(not(miri), target_os = "emscripten"))] +const TEST_LENGTHS: &[usize] = &[ + 2, 3, 4, 5, 6, 7, 8, 9, 10, 15, 16, 17, 20, 24, 30, 32, 33, 35, 50, 100, 200, 500, 1_000, + 2_048, 5_000, 10_000, 100_000, +]; + +#[cfg(all(not(miri), not(target_os = "emscripten")))] const TEST_LENGTHS: &[usize] = &[ 2, 3, 4, 5, 6, 7, 8, 9, 10, 15, 16, 17, 20, 24, 30, 32, 33, 35, 50, 100, 200, 500, 1_000, 2_048, 5_000, 10_000, 100_000, 1_100_000, diff --git a/library/alloc/tests/sync.rs b/library/alloc/tests/sync.rs index 7a9a4abfdc67..6d3ab1b1d11e 100644 --- a/library/alloc/tests/sync.rs +++ b/library/alloc/tests/sync.rs @@ -128,6 +128,7 @@ fn try_unwrap() { } #[test] +#[cfg_attr(any(target_os = "emscripten", target_os = "wasi"), ignore)] // no threads fn into_inner() { for _ in 0..100 // ^ Increase chances of hitting potential race conditions diff --git a/library/std/src/io/copy/tests.rs b/library/std/src/io/copy/tests.rs index 2e0eb6cdce66..25b1ece2745b 100644 --- a/library/std/src/io/copy/tests.rs +++ b/library/std/src/io/copy/tests.rs @@ -126,6 +126,7 @@ mod io_benches { use crate::io::prelude::*; #[bench] + #[cfg_attr(target_os = "emscripten", ignore)] // no /dev fn bench_copy_buf_reader(b: &mut Bencher) { let mut file_in = File::open("/dev/zero").expect("opening /dev/zero failed"); // use dyn to avoid specializations unrelated to readbuf diff --git a/library/std/tests/pipe_subprocess.rs b/library/std/tests/pipe_subprocess.rs index df946cdcf2b7..00d99a578d58 100644 --- a/library/std/tests/pipe_subprocess.rs +++ b/library/std/tests/pipe_subprocess.rs @@ -1,7 +1,7 @@ #![feature(anonymous_pipe)] fn main() { - #[cfg(all(not(miri), any(unix, windows)))] + #[cfg(all(not(miri), any(unix, windows), not(target_os = "emscripten")))] { use std::io::{Read, pipe}; use std::{env, process}; diff --git a/library/std/tests/process_spawning.rs b/library/std/tests/process_spawning.rs index 3e72e371ade1..43b45cb2d2b5 100644 --- a/library/std/tests/process_spawning.rs +++ b/library/std/tests/process_spawning.rs @@ -5,7 +5,8 @@ use std::{env, fs, process, str}; mod common; #[test] -#[cfg_attr(any(miri, target_os = "wasi"), ignore)] // Process spawning not supported by Miri and wasi +// Process spawning not supported by Miri, Emscripten and wasi +#[cfg_attr(any(miri, target_os = "emscripten", target_os = "wasi"), ignore)] fn issue_15149() { // If we're the parent, copy our own binary to a new directory. let my_path = env::current_exe().unwrap(); From 88ff147c567656bc033eb7a1441b173d235ac465 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Thu, 23 Jan 2025 19:03:12 +0000 Subject: [PATCH 18/81] Remove a bunch of emscripten test ignores They are either outdated as emscripten now supports i128 or they are subsumed by #[cfg_attr(not(panic = "unwind"), ignore] --- .../alloc/tests/collections/binary_heap.rs | 2 - library/alloc/tests/lib.rs | 3 -- library/alloc/tests/slice.rs | 1 - library/alloc/tests/vec.rs | 4 -- library/core/tests/hash/mod.rs | 3 -- library/core/tests/num/flt2dec/random.rs | 6 --- library/core/tests/num/ops.rs | 52 +++++++++++-------- library/core/tests/num/wrapping.rs | 2 - library/std/src/f64/tests.rs | 3 -- library/std/src/io/tests.rs | 2 - library/test/src/tests.rs | 10 ---- 11 files changed, 29 insertions(+), 59 deletions(-) diff --git a/library/alloc/tests/collections/binary_heap.rs b/library/alloc/tests/collections/binary_heap.rs index 55405ffe8c4f..95f4c3e614f5 100644 --- a/library/alloc/tests/collections/binary_heap.rs +++ b/library/alloc/tests/collections/binary_heap.rs @@ -502,9 +502,7 @@ fn test_retain_catch_unwind() { // even if the order might not be correct. // // Destructors must be called exactly once per element. -// FIXME: re-enable emscripten once it can unwind again #[test] -#[cfg(not(target_os = "emscripten"))] #[cfg_attr(not(panic = "unwind"), ignore = "test requires unwinding support")] fn panic_safe() { use std::cmp; diff --git a/library/alloc/tests/lib.rs b/library/alloc/tests/lib.rs index 393bdfe48b74..372df2c17101 100644 --- a/library/alloc/tests/lib.rs +++ b/library/alloc/tests/lib.rs @@ -93,9 +93,6 @@ fn test_rng() -> rand_xorshift::XorShiftRng { rand::SeedableRng::from_seed(seed) } -// FIXME: Instantiated functions with i128 in the signature is not supported in Emscripten. -// See https://github.com/kripken/emscripten-fastcomp/issues/169 -#[cfg(not(target_os = "emscripten"))] #[test] fn test_boxed_hasher() { let ordinary_hash = hash(&5u32); diff --git a/library/alloc/tests/slice.rs b/library/alloc/tests/slice.rs index 9625e3d2b5e0..f990a41b679f 100644 --- a/library/alloc/tests/slice.rs +++ b/library/alloc/tests/slice.rs @@ -1414,7 +1414,6 @@ fn test_box_slice_clone() { #[test] #[allow(unused_must_use)] // here, we care about the side effects of `.clone()` -#[cfg_attr(target_os = "emscripten", ignore)] #[cfg_attr(not(panic = "unwind"), ignore = "test requires unwinding support")] fn test_box_slice_clone_panics() { use std::sync::Arc; diff --git a/library/alloc/tests/vec.rs b/library/alloc/tests/vec.rs index b24daec2968e..fe1db56414e0 100644 --- a/library/alloc/tests/vec.rs +++ b/library/alloc/tests/vec.rs @@ -1587,9 +1587,7 @@ fn extract_if_complex() { } } -// FIXME: re-enable emscripten once it can unwind again #[test] -#[cfg(not(target_os = "emscripten"))] #[cfg_attr(not(panic = "unwind"), ignore = "test requires unwinding support")] fn extract_if_consumed_panic() { use std::rc::Rc; @@ -1640,9 +1638,7 @@ fn extract_if_consumed_panic() { } } -// FIXME: Re-enable emscripten once it can catch panics #[test] -#[cfg(not(target_os = "emscripten"))] #[cfg_attr(not(panic = "unwind"), ignore = "test requires unwinding support")] fn extract_if_unconsumed_panic() { use std::rc::Rc; diff --git a/library/core/tests/hash/mod.rs b/library/core/tests/hash/mod.rs index 9f14995f73fe..1f10a4733b05 100644 --- a/library/core/tests/hash/mod.rs +++ b/library/core/tests/hash/mod.rs @@ -141,9 +141,6 @@ fn test_custom_state() { // const { assert!(hash(&Custom { hash: 6 }) == 6) }; } -// FIXME: Instantiated functions with i128 in the signature is not supported in Emscripten. -// See https://github.com/kripken/emscripten-fastcomp/issues/169 -#[cfg(not(target_os = "emscripten"))] #[test] fn test_indirect_hasher() { let mut hasher = MyHasher { hash: 0 }; diff --git a/library/core/tests/num/flt2dec/random.rs b/library/core/tests/num/flt2dec/random.rs index 99fc23af7ea9..90042ae03bf7 100644 --- a/library/core/tests/num/flt2dec/random.rs +++ b/library/core/tests/num/flt2dec/random.rs @@ -84,9 +84,6 @@ where F: for<'a> FnMut(&Decoded, &'a mut [MaybeUninit]) -> Option<(&'a [u8], i16)>, G: for<'a> FnMut(&Decoded, &'a mut [MaybeUninit]) -> (&'a [u8], i16), { - if cfg!(target_os = "emscripten") { - return; // using rng pulls in i128 support, which doesn't work - } let mut rng = crate::test_rng(); let f32_range = Uniform::new(0x0000_0001u32, 0x7f80_0000); iterate("f32_random_equivalence_test", k, n, f, g, |_| { @@ -100,9 +97,6 @@ where F: for<'a> FnMut(&Decoded, &'a mut [MaybeUninit]) -> Option<(&'a [u8], i16)>, G: for<'a> FnMut(&Decoded, &'a mut [MaybeUninit]) -> (&'a [u8], i16), { - if cfg!(target_os = "emscripten") { - return; // using rng pulls in i128 support, which doesn't work - } let mut rng = crate::test_rng(); let f64_range = Uniform::new(0x0000_0000_0000_0001u64, 0x7ff0_0000_0000_0000); iterate("f64_random_equivalence_test", k, n, f, g, |_| { diff --git a/library/core/tests/num/ops.rs b/library/core/tests/num/ops.rs index ae8b938250ec..7b2aad489780 100644 --- a/library/core/tests/num/ops.rs +++ b/library/core/tests/num/ops.rs @@ -51,9 +51,7 @@ macro_rules! test_op { }; } -test_op!(test_neg_defined, Neg::neg(0), 0, i8, i16, i32, i64, f32, f64); -#[cfg(not(target_os = "emscripten"))] -test_op!(test_neg_defined_128, Neg::neg(0), 0, i128); +test_op!(test_neg_defined, Neg::neg(0), 0, i8, i16, i32, i64, i128, f32, f64); test_op!(test_not_defined_bool, Not::not(true), false, bool); @@ -69,17 +67,17 @@ macro_rules! test_arith_op { i16, i32, i64, + i128, isize, u8, u16, u32, u64, + u128, usize, f32, f64 ); - #[cfg(not(target_os = "emscripten"))] - impls_defined!($op, $method($lhs, $rhs), 0, i128, u128); } }; ($fn_name:ident, $op:ident::$method:ident(&mut $lhs:literal, $rhs:literal)) => { @@ -93,17 +91,17 @@ macro_rules! test_arith_op { i16, i32, i64, + i128, isize, u8, u16, u32, u64, + u128, usize, f32, f64 ); - #[cfg(not(target_os = "emscripten"))] - impls_defined!($op, $method(&mut $lhs, $rhs), 0, i128, u128); } }; } @@ -131,15 +129,15 @@ macro_rules! test_bitop { i16, i32, i64, + i128, isize, u8, u16, u32, u64, + u128, usize ); - #[cfg(not(target_os = "emscripten"))] - impls_defined!($op, $method(0, 0), 0, i128, u128); impls_defined!($op, $method(false, false), false, bool); } }; @@ -156,15 +154,15 @@ macro_rules! test_bitop_assign { i16, i32, i64, + i128, isize, u8, u16, u32, u64, + u128, usize ); - #[cfg(not(target_os = "emscripten"))] - impls_defined!($op, $method(&mut 0, 0), 0, i128, u128); impls_defined!($op, $method(&mut false, false), false, bool); } }; @@ -182,9 +180,11 @@ macro_rules! test_shift_inner { $(impl_defined!($op, $method(0,0), 0, $lt, $rt);)+ }; ($op:ident::$method:ident, $lt:ty) => { - test_shift_inner!($op::$method, $lt, i8, i16, i32, i64, isize, u8, u16, u32, u64, usize); - #[cfg(not(target_os = "emscripten"))] - test_shift_inner!($op::$method, $lt, i128, u128); + test_shift_inner!( + $op::$method, $lt, + i8, i16, i32, i64, i128, isize, + u8, u16, u32, u64, u128, usize + ); }; } @@ -195,9 +195,11 @@ macro_rules! test_shift { ($test_name:ident, $op:ident::$method:ident) => { #[test] fn $test_name() { - test_shift!($op::$method, i8, i16, i32, i64, isize, u8, u16, u32, u64, usize); - #[cfg(not(target_os = "emscripten"))] - test_shift!($op::$method, i128, u128); + test_shift!( + $op::$method, + i8, i16, i32, i64, i128, isize, + u8, u16, u32, u64, u128, usize + ); } }; } @@ -207,9 +209,11 @@ macro_rules! test_shift_assign_inner { $(impl_defined!($op, $method(&mut 0,0), 0, $lt, $rt);)+ }; ($op:ident::$method:ident, $lt:ty) => { - test_shift_assign_inner!($op::$method, $lt, i8, i16, i32, i64, isize, u8, u16, u32, u64, usize); - #[cfg(not(target_os = "emscripten"))] - test_shift_assign_inner!($op::$method, $lt, i128, u128); + test_shift_assign_inner!( + $op::$method, $lt, + i8, i16, i32, i64, i128, isize, + u8, u16, u32, u64, u128, usize + ); }; } @@ -220,9 +224,11 @@ macro_rules! test_shift_assign { ($test_name:ident, $op:ident::$method:ident) => { #[test] fn $test_name() { - test_shift_assign!($op::$method, i8, i16, i32, i64, isize, u8, u16, u32, u64, usize); - #[cfg(not(target_os = "emscripten"))] - test_shift_assign!($op::$method, i128, u128); + test_shift_assign!( + $op::$method, + i8, i16, i32, i64, i128, isize, + u8, u16, u32, u64, u128, usize + ); } }; } diff --git a/library/core/tests/num/wrapping.rs b/library/core/tests/num/wrapping.rs index c5a719883951..0b9fca8455b8 100644 --- a/library/core/tests/num/wrapping.rs +++ b/library/core/tests/num/wrapping.rs @@ -64,14 +64,12 @@ wrapping_test!(test_wrapping_i8, i8, i8::MIN, i8::MAX); wrapping_test!(test_wrapping_i16, i16, i16::MIN, i16::MAX); wrapping_test!(test_wrapping_i32, i32, i32::MIN, i32::MAX); wrapping_test!(test_wrapping_i64, i64, i64::MIN, i64::MAX); -#[cfg(not(target_os = "emscripten"))] wrapping_test!(test_wrapping_i128, i128, i128::MIN, i128::MAX); wrapping_test!(test_wrapping_isize, isize, isize::MIN, isize::MAX); wrapping_test!(test_wrapping_u8, u8, u8::MIN, u8::MAX); wrapping_test!(test_wrapping_u16, u16, u16::MIN, u16::MAX); wrapping_test!(test_wrapping_u32, u32, u32::MIN, u32::MAX); wrapping_test!(test_wrapping_u64, u64, u64::MIN, u64::MAX); -#[cfg(not(target_os = "emscripten"))] wrapping_test!(test_wrapping_u128, u128, u128::MIN, u128::MAX); wrapping_test!(test_wrapping_usize, usize, usize::MIN, usize::MAX); diff --git a/library/std/src/f64/tests.rs b/library/std/src/f64/tests.rs index 3fac2efe0d76..f5ba2c7b594e 100644 --- a/library/std/src/f64/tests.rs +++ b/library/std/src/f64/tests.rs @@ -112,7 +112,6 @@ fn test_neg_zero() { assert_eq!(Fp::Zero, neg_zero.classify()); } -#[cfg_attr(all(target_arch = "wasm32", target_os = "emscripten"), ignore)] // issue 42630 #[test] fn test_one() { let one: f64 = 1.0f64; @@ -165,7 +164,6 @@ fn test_is_finite() { assert!((-109.2f64).is_finite()); } -#[cfg_attr(all(target_arch = "wasm32", target_os = "emscripten"), ignore)] // issue 42630 #[test] fn test_is_normal() { let nan: f64 = f64::NAN; @@ -183,7 +181,6 @@ fn test_is_normal() { assert!(!1e-308f64.is_normal()); } -#[cfg_attr(all(target_arch = "wasm32", target_os = "emscripten"), ignore)] // issue 42630 #[test] fn test_classify() { let nan: f64 = f64::NAN; diff --git a/library/std/src/io/tests.rs b/library/std/src/io/tests.rs index 85098b3bb181..226cc6011bca 100644 --- a/library/std/src/io/tests.rs +++ b/library/std/src/io/tests.rs @@ -7,7 +7,6 @@ use crate::mem::MaybeUninit; use crate::ops::Deref; #[test] -#[cfg_attr(target_os = "emscripten", ignore)] fn read_until() { let mut buf = Cursor::new(&b"12"[..]); let mut v = Vec::new(); @@ -359,7 +358,6 @@ fn chain_zero_length_read_is_not_eof() { } #[bench] -#[cfg_attr(target_os = "emscripten", ignore)] #[cfg_attr(miri, ignore)] // Miri isn't fast... fn bench_read_to_end(b: &mut test::Bencher) { b.iter(|| { diff --git a/library/test/src/tests.rs b/library/test/src/tests.rs index abeb36421697..47f581fefae1 100644 --- a/library/test/src/tests.rs +++ b/library/test/src/tests.rs @@ -133,9 +133,7 @@ fn ignored_tests_result_in_ignored() { assert_eq!(result, TrIgnored); } -// FIXME: Re-enable emscripten once it can catch panics again (introduced by #65251) #[test] -#[cfg(not(target_os = "emscripten"))] #[cfg_attr(not(panic = "unwind"), ignore = "test requires unwinding support")] fn test_should_panic() { fn f() -> Result<(), String> { @@ -164,9 +162,7 @@ fn test_should_panic() { assert_eq!(result, TrOk); } -// FIXME: Re-enable emscripten once it can catch panics again (introduced by #65251) #[test] -#[cfg(not(target_os = "emscripten"))] #[cfg_attr(not(panic = "unwind"), ignore = "test requires unwinding support")] fn test_should_panic_good_message() { fn f() -> Result<(), String> { @@ -195,9 +191,7 @@ fn test_should_panic_good_message() { assert_eq!(result, TrOk); } -// FIXME: Re-enable emscripten once it can catch panics again (introduced by #65251) #[test] -#[cfg(not(target_os = "emscripten"))] #[cfg_attr(not(panic = "unwind"), ignore = "test requires unwinding support")] fn test_should_panic_bad_message() { use crate::tests::TrFailedMsg; @@ -231,9 +225,7 @@ fn test_should_panic_bad_message() { assert_eq!(result, TrFailedMsg(failed_msg.to_string())); } -// FIXME: Re-enable emscripten once it can catch panics again (introduced by #65251) #[test] -#[cfg(not(target_os = "emscripten"))] #[cfg_attr(not(panic = "unwind"), ignore = "test requires unwinding support")] fn test_should_panic_non_string_message_type() { use std::any::TypeId; @@ -272,9 +264,7 @@ fn test_should_panic_non_string_message_type() { assert_eq!(result, TrFailedMsg(failed_msg)); } -// FIXME: Re-enable emscripten once it can catch panics again (introduced by #65251) #[test] -#[cfg(not(target_os = "emscripten"))] #[cfg_attr(not(panic = "unwind"), ignore = "test requires unwinding support")] fn test_should_panic_but_succeeds() { let should_panic_variants = [ShouldPanic::Yes, ShouldPanic::YesWithMessage("error message")]; From a20996c180107a676306c3623add30811f9b40a7 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Thu, 23 Jan 2025 19:07:24 +0000 Subject: [PATCH 19/81] Update a bunch of comments from before wasi support was added --- library/std/src/sys/alloc/wasm.rs | 4 ++-- library/std/src/sys/pal/wasi/mod.rs | 3 +-- library/std/src/sys/pal/wasm/mod.rs | 2 +- 3 files changed, 4 insertions(+), 5 deletions(-) diff --git a/library/std/src/sys/alloc/wasm.rs b/library/std/src/sys/alloc/wasm.rs index a308fafc68b1..53fbc9529e59 100644 --- a/library/std/src/sys/alloc/wasm.rs +++ b/library/std/src/sys/alloc/wasm.rs @@ -1,6 +1,6 @@ //! This is an implementation of a global allocator on wasm targets when -//! emscripten is not in use. In that situation there's no actual runtime for us -//! to lean on for allocation, so instead we provide our own! +//! emscripten or wasi is not in use. In that situation there's no actual runtime +//! for us to lean on for allocation, so instead we provide our own! //! //! The wasm instruction set has two instructions for getting the current //! amount of memory and growing the amount of memory. These instructions are the diff --git a/library/std/src/sys/pal/wasi/mod.rs b/library/std/src/sys/pal/wasi/mod.rs index 5d54c7903065..361802d101df 100644 --- a/library/std/src/sys/pal/wasi/mod.rs +++ b/library/std/src/sys/pal/wasi/mod.rs @@ -1,8 +1,7 @@ //! System bindings for the wasm/web platform //! //! This module contains the facade (aka platform-specific) implementations of -//! OS level functionality for wasm. Note that this wasm is *not* the emscripten -//! wasm, so we have no runtime here. +//! OS level functionality for wasm. //! //! This is all super highly experimental and not actually intended for //! wide/production use yet, it's still all in the experimental category. This diff --git a/library/std/src/sys/pal/wasm/mod.rs b/library/std/src/sys/pal/wasm/mod.rs index 8141bfac49aa..41fe019f1102 100644 --- a/library/std/src/sys/pal/wasm/mod.rs +++ b/library/std/src/sys/pal/wasm/mod.rs @@ -2,7 +2,7 @@ //! //! This module contains the facade (aka platform-specific) implementations of //! OS level functionality for wasm. Note that this wasm is *not* the emscripten -//! wasm, so we have no runtime here. +//! or wasi wasm, so we have no runtime here. //! //! This is all super highly experimental and not actually intended for //! wide/production use yet, it's still all in the experimental category. This From 6b18473a212d7c60e840504b9d013e7aff554239 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Fri, 24 Jan 2025 09:26:55 +0000 Subject: [PATCH 20/81] Update target docs to mention MAXIMUM_MEMORY=2GB --- src/doc/rustc/src/platform-support/wasm32-unknown-emscripten.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/doc/rustc/src/platform-support/wasm32-unknown-emscripten.md b/src/doc/rustc/src/platform-support/wasm32-unknown-emscripten.md index 7a9cd4b522b9..d364852b1c1d 100644 --- a/src/doc/rustc/src/platform-support/wasm32-unknown-emscripten.md +++ b/src/doc/rustc/src/platform-support/wasm32-unknown-emscripten.md @@ -118,7 +118,7 @@ This target is not extensively tested in CI for the rust-lang/rust repository. I can be tested locally, for example, with: ```sh -./x.py test --target wasm32-unknown-emscripten --skip src/tools/linkchecker +EMCC_CFLAGS="-s MAXIMUM_MEMORY=2GB" ./x.py test --target wasm32-unknown-emscripten --skip src/tools/linkchecker ``` To run these tests, both `emcc` and `node` need to be in your `$PATH`. You can From bc0170a43bd6e4f5beef12900d76a2aef89844af Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Fri, 24 Jan 2025 12:15:11 +0000 Subject: [PATCH 21/81] Add a workaround for parallel rustc crashing when there are delayed bugs This doesn't fix the root cause of this crash, but at least stops it from happening for the time being. --- compiler/rustc_middle/src/ty/context.rs | 45 ++++++++++++++++--------- 1 file changed, 30 insertions(+), 15 deletions(-) diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index 2d76f6ec7d69..00e5f4f3465d 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -1349,6 +1349,33 @@ pub struct GlobalCtxt<'tcx> { /// Stores memory for globals (statics/consts). pub(crate) alloc_map: Lock>, + + current_gcx: CurrentGcx, +} + +impl<'tcx> GlobalCtxt<'tcx> { + /// Installs `self` in a `TyCtxt` and `ImplicitCtxt` for the duration of + /// `f`. + pub fn enter(&'tcx self, f: F) -> R + where + F: FnOnce(TyCtxt<'tcx>) -> R, + { + let icx = tls::ImplicitCtxt::new(self); + + // Reset `current_gcx` to `None` when we exit. + let _on_drop = defer(move || { + *self.current_gcx.value.write() = None; + }); + + // Set this `GlobalCtxt` as the current one. + { + let mut guard = self.current_gcx.value.write(); + assert!(guard.is_none(), "no `GlobalCtxt` is currently set"); + *guard = Some(self as *const _ as *const ()); + } + + tls::enter_context(&icx, || f(icx.tcx)) + } } /// This is used to get a reference to a `GlobalCtxt` if one is available. @@ -1539,23 +1566,11 @@ impl<'tcx> TyCtxt<'tcx> { canonical_param_env_cache: Default::default(), data_layout, alloc_map: Lock::new(interpret::AllocMap::new()), + current_gcx, }); - let icx = tls::ImplicitCtxt::new(&gcx); - - // Reset `current_gcx` to `None` when we exit. - let _on_drop = defer(|| { - *current_gcx.value.write() = None; - }); - - // Set this `GlobalCtxt` as the current one. - { - let mut guard = current_gcx.value.write(); - assert!(guard.is_none(), "no `GlobalCtxt` is currently set"); - *guard = Some(&gcx as *const _ as *const ()); - } - - tls::enter_context(&icx, || f(icx.tcx)) + // This is a separate function to work around a crash with parallel rustc (#135870) + gcx.enter(f) } /// Obtain all lang items of this crate and all dependencies (recursively) From 84c80151cf496d0c6e6823493fd4a07d242ce311 Mon Sep 17 00:00:00 2001 From: Florian Bartels Date: Thu, 28 Nov 2024 14:06:34 +0100 Subject: [PATCH 22/81] Add new target for supporting Neutrino QNX 6.1 with `io-socket` network stack on aarch64 Signed-off-by: Florian Bartels --- compiler/rustc_target/src/spec/mod.rs | 1 + .../aarch64_unknown_nto_qnx710_iosock.rs | 27 +++++++++++++++++++ library/std/Cargo.toml | 3 ++- .../src/sys/pal/unix/process/process_unix.rs | 7 ++--- src/bootstrap/src/core/sanity.rs | 1 + src/doc/rustc/src/platform-support.md | 4 ++- src/doc/rustc/src/platform-support/nto-qnx.md | 15 ++++++++--- tests/assembly/targets/targets-elf.rs | 3 +++ tests/ui/check-cfg/well-known-values.stderr | 2 +- 9 files changed, 54 insertions(+), 9 deletions(-) create mode 100644 compiler/rustc_target/src/spec/targets/aarch64_unknown_nto_qnx710_iosock.rs diff --git a/compiler/rustc_target/src/spec/mod.rs b/compiler/rustc_target/src/spec/mod.rs index 37564ab38fca..df6d117f3760 100644 --- a/compiler/rustc_target/src/spec/mod.rs +++ b/compiler/rustc_target/src/spec/mod.rs @@ -1963,6 +1963,7 @@ supported_targets! { ("aarch64-unknown-nto-qnx700", aarch64_unknown_nto_qnx700), ("aarch64-unknown-nto-qnx710", aarch64_unknown_nto_qnx710), + ("aarch64-unknown-nto-qnx710_iosock", aarch64_unknown_nto_qnx710_iosock), ("x86_64-pc-nto-qnx710", x86_64_pc_nto_qnx710), ("i586-pc-nto-qnx700", i586_pc_nto_qnx700), diff --git a/compiler/rustc_target/src/spec/targets/aarch64_unknown_nto_qnx710_iosock.rs b/compiler/rustc_target/src/spec/targets/aarch64_unknown_nto_qnx710_iosock.rs new file mode 100644 index 000000000000..c9ffc0e072c3 --- /dev/null +++ b/compiler/rustc_target/src/spec/targets/aarch64_unknown_nto_qnx710_iosock.rs @@ -0,0 +1,27 @@ +use crate::spec::{Cc, LinkerFlavor, Lld, Target, TargetOptions}; + +pub(crate) fn target() -> Target { + let mut target = super::aarch64_unknown_nto_qnx710::target(); + target.options.env = "nto71_iosock".into(); + target.options.pre_link_args = + TargetOptions::link_args(LinkerFlavor::Gnu(Cc::Yes, Lld::No), &[ + "-Vgcc_ntoaarch64le_cxx", + get_iosock_param(), + ]); + target +} + +// When using `io-sock` on QNX, we must add a search path for the linker so +// that it prefers the io-sock version. +// The path depends on the host, i.e. we cannot hard-code it here, but have +// to determine it when the compiler runs. +// When using the QNX toolchain, the environment variable QNX_TARGET is always set. +// More information: +// https://www.qnx.com/developers/docs/7.1/index.html#com.qnx.doc.neutrino.io_sock/topic/migrate_app.html +fn get_iosock_param() -> &'static str { + let target_dir = + std::env::var("QNX_TARGET").unwrap_or_else(|_| "PLEASE_SET_ENV_VAR_QNX_TARGET".into()); + let linker_param = format!("-L{target_dir}/aarch64le/io-sock/lib"); + + linker_param.leak() +} diff --git a/library/std/Cargo.toml b/library/std/Cargo.toml index da58d7c13bd1..b91b89b7761b 100644 --- a/library/std/Cargo.toml +++ b/library/std/Cargo.toml @@ -139,7 +139,8 @@ test = true level = "warn" check-cfg = [ 'cfg(bootstrap)', - 'cfg(target_arch, values("xtensa"))', + 'cfg(target_arch, values("xtensa", "aarch64-unknown-nto-qnx710_iosock"))', + 'cfg(target_env, values("nto71_iosock"))', # std use #[path] imports to portable-simd `std_float` crate # and to the `backtrace` crate which messes-up with Cargo list # of declared features, we therefor expect any feature cfg diff --git a/library/std/src/sys/pal/unix/process/process_unix.rs b/library/std/src/sys/pal/unix/process/process_unix.rs index ec4965c1d719..cc22b3ecbd0f 100644 --- a/library/std/src/sys/pal/unix/process/process_unix.rs +++ b/library/std/src/sys/pal/unix/process/process_unix.rs @@ -20,7 +20,7 @@ use crate::{fmt, mem, sys}; cfg_if::cfg_if! { // This workaround is only needed for QNX 7.0 and 7.1. The bug should have been fixed in 8.0 - if #[cfg(any(target_env = "nto70", target_env = "nto71"))] { + if #[cfg(any(target_env = "nto70", target_env = "nto71", target_env = "nto71_iosock"))] { use crate::thread; use libc::{c_char, posix_spawn_file_actions_t, posix_spawnattr_t}; use crate::time::Duration; @@ -191,7 +191,8 @@ impl Command { target_os = "watchos", target_os = "tvos", target_env = "nto70", - target_env = "nto71" + target_env = "nto71", + target_env = "nto71_iosock", )))] unsafe fn do_fork(&mut self) -> Result { cvt(libc::fork()) @@ -202,7 +203,7 @@ impl Command { // Documentation says "... or try calling fork() again". This is what we do here. // See also https://www.qnx.com/developers/docs/7.1/#com.qnx.doc.neutrino.lib_ref/topic/f/fork.html // This workaround is only needed for QNX 7.0 and 7.1. The bug should have been fixed in 8.0 - #[cfg(any(target_env = "nto70", target_env = "nto71"))] + #[cfg(any(target_env = "nto70", target_env = "nto71", target_env = "nto71_iosock"))] unsafe fn do_fork(&mut self) -> Result { use crate::sys::os::errno; diff --git a/src/bootstrap/src/core/sanity.rs b/src/bootstrap/src/core/sanity.rs index ed0155622c22..418ebbbfb42c 100644 --- a/src/bootstrap/src/core/sanity.rs +++ b/src/bootstrap/src/core/sanity.rs @@ -34,6 +34,7 @@ pub struct Finder { // Targets can be removed from this list once they are present in the stage0 compiler (usually by updating the beta compiler of the bootstrap). const STAGE0_MISSING_TARGETS: &[&str] = &[ // just a dummy comment so the list doesn't get onelined + "aarch64-unknown-nto-qnx710_iosock", ]; /// Minimum version threshold for libstdc++ required when using prebuilt LLVM diff --git a/src/doc/rustc/src/platform-support.md b/src/doc/rustc/src/platform-support.md index a706926f7435..d25eaa49dd5e 100644 --- a/src/doc/rustc/src/platform-support.md +++ b/src/doc/rustc/src/platform-support.md @@ -254,12 +254,14 @@ target | std | host | notes [`aarch64-kmc-solid_asp3`](platform-support/kmc-solid.md) | ✓ | | ARM64 SOLID with TOPPERS/ASP3 [`aarch64-nintendo-switch-freestanding`](platform-support/aarch64-nintendo-switch-freestanding.md) | * | | ARM64 Nintendo Switch, Horizon [`aarch64-unknown-freebsd`](platform-support/freebsd.md) | ✓ | ✓ | ARM64 FreeBSD +`aarch64-unknown-freebsd` | ✓ | ✓ | ARM64 FreeBSD [`aarch64-unknown-hermit`](platform-support/hermit.md) | ✓ | | ARM64 Hermit [`aarch64-unknown-illumos`](platform-support/illumos.md) | ✓ | ✓ | ARM64 illumos `aarch64-unknown-linux-gnu_ilp32` | ✓ | ✓ | ARM64 Linux (ILP32 ABI) [`aarch64-unknown-netbsd`](platform-support/netbsd.md) | ✓ | ✓ | ARM64 NetBSD -[`aarch64-unknown-nto-qnx700`](platform-support/nto-qnx.md) | ? | | ARM64 QNX Neutrino 7.0 RTOS | +[`aarch64-unknown-nto-qnx710_iosock`](platform-support/nto-qnx.md) | ✓ | | ARM64 QNX Neutrino 7.1 RTOS with new network stack (io-sock) | [`aarch64-unknown-nto-qnx710`](platform-support/nto-qnx.md) | ✓ | | ARM64 QNX Neutrino 7.1 RTOS | +[`aarch64-unknown-nto-qnx710`](platform-support/nto-qnx.md) | ✓ | | ARM64 QNX Neutrino 7.1 RTOS with default network stack (io-pkt) | [`aarch64-unknown-nuttx`](platform-support/nuttx.md) | * | | ARM64 with NuttX [`aarch64-unknown-openbsd`](platform-support/openbsd.md) | ✓ | ✓ | ARM64 OpenBSD [`aarch64-unknown-redox`](platform-support/redox.md) | ✓ | | ARM64 Redox OS diff --git a/src/doc/rustc/src/platform-support/nto-qnx.md b/src/doc/rustc/src/platform-support/nto-qnx.md index 96e3b58f4715..7d6d9ff3223c 100644 --- a/src/doc/rustc/src/platform-support/nto-qnx.md +++ b/src/doc/rustc/src/platform-support/nto-qnx.md @@ -22,11 +22,15 @@ Currently, the following QNX Neutrino versions and compilation targets are suppo | QNX Neutrino Version | Target Architecture | Full support | `no_std` support | |----------------------|---------------------|:------------:|:----------------:| -| 7.1 | AArch64 | ✓ | ✓ | +| 7.1 with io-pkt | AArch64 | ✓ | ✓ | +| 7.1 with io-sock | AArch64 | ✓ | ✓ | | 7.1 | x86_64 | ✓ | ✓ | | 7.0 | AArch64 | ? | ✓ | | 7.0 | x86 | | ✓ | +On QNX 7.0 and 7.1, `io-pkt` is used as network stack by default. QNX 7.1 includes +the optional network stack `io-sock`. + Adding other architectures that are supported by QNX Neutrino is possible. In the table above, 'full support' indicates support for building Rust applications with the full standard library. @@ -107,7 +111,8 @@ There are no further known requirements. For conditional compilation, following QNX Neutrino specific attributes are defined: - `target_os` = `"nto"` -- `target_env` = `"nto71"` (for QNX Neutrino 7.1) +- `target_env` = `"nto71"` (for QNX Neutrino 7.1 with "classic" network stack "io_pkt") +- `target_env` = `"nto71_iosock"` (for QNX Neutrino 7.1 with network stack "io_sock") - `target_env` = `"nto70"` (for QNX Neutrino 7.0) ## Building the target @@ -134,6 +139,10 @@ export build_env=' CFLAGS_aarch64-unknown-nto-qnx710=-Vgcc_ntoaarch64le_cxx CXX_aarch64-unknown-nto-qnx710=qcc AR_aarch64_unknown_nto_qnx710=ntoaarch64-ar + CC_aarch64-unknown-nto-qnx710_iosock=qcc + CFLAGS_aarch64-unknown-nto-qnx710_iosock=-Vgcc_ntoaarch64le_cxx + CXX_aarch64-unknown-nto-qnx710_iosock=qcc + AR_aarch64_unknown_nto_qnx710_iosock=ntoaarch64-ar CC_x86_64-pc-nto-qnx710=qcc CFLAGS_x86_64-pc-nto-qnx710=-Vgcc_ntox86_64_cxx CXX_x86_64-pc-nto-qnx710=qcc @@ -141,7 +150,7 @@ export build_env=' env $build_env \ ./x.py build \ - --target aarch64-unknown-nto-qnx710,x86_64-pc-nto-qnx710,x86_64-unknown-linux-gnu \ + --target aarch64-unknown-nto-qnx710_iosock,aarch64-unknown-nto-qnx710,x86_64-pc-nto-qnx710,x86_64-unknown-linux-gnu \ rustc library/core library/alloc library/std ``` diff --git a/tests/assembly/targets/targets-elf.rs b/tests/assembly/targets/targets-elf.rs index 6bb3389c4095..b9d6aaf7929b 100644 --- a/tests/assembly/targets/targets-elf.rs +++ b/tests/assembly/targets/targets-elf.rs @@ -57,6 +57,9 @@ //@ revisions: aarch64_unknown_nto_qnx710 //@ [aarch64_unknown_nto_qnx710] compile-flags: --target aarch64-unknown-nto-qnx710 //@ [aarch64_unknown_nto_qnx710] needs-llvm-components: aarch64 +//@ revisions: aarch64_unknown_nto_qnx710_iosock +//@ [aarch64_unknown_nto_qnx710_iosock] compile-flags: --target aarch64-unknown-nto-qnx710_iosock +//@ [aarch64_unknown_nto_qnx710_iosock] needs-llvm-components: aarch64 //@ revisions: aarch64_unknown_openbsd //@ [aarch64_unknown_openbsd] compile-flags: --target aarch64-unknown-openbsd //@ [aarch64_unknown_openbsd] needs-llvm-components: aarch64 diff --git a/tests/ui/check-cfg/well-known-values.stderr b/tests/ui/check-cfg/well-known-values.stderr index 5c1898a0ae36..29bc30815b87 100644 --- a/tests/ui/check-cfg/well-known-values.stderr +++ b/tests/ui/check-cfg/well-known-values.stderr @@ -156,7 +156,7 @@ warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE` LL | target_env = "_UNEXPECTED_VALUE", | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = note: expected values for `target_env` are: ``, `gnu`, `msvc`, `musl`, `newlib`, `nto70`, `nto71`, `ohos`, `p1`, `p2`, `relibc`, `sgx`, and `uclibc` + = note: expected values for `target_env` are: ``, `gnu`, `msvc`, `musl`, `newlib`, `nto70`, `nto71`, `nto71_iosock`, `ohos`, `p1`, `p2`, `relibc`, `sgx`, and `uclibc` = note: see for more information about checking conditional configuration warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE` From efe53ddd587333a405fcb95d78a72696932275cd Mon Sep 17 00:00:00 2001 From: Florian Bartels Date: Fri, 29 Nov 2024 18:15:05 +0100 Subject: [PATCH 23/81] Add support for QNX 7.1 with io-sock on x64 Signed-off-by: Florian Bartels --- compiler/rustc_target/src/spec/mod.rs | 1 + .../targets/x86_64_pc_nto_qnx710_iosock.rs | 27 +++++++++++++++++++ library/std/Cargo.toml | 2 +- src/bootstrap/src/core/sanity.rs | 1 + src/doc/rustc/src/platform-support.md | 3 ++- src/doc/rustc/src/platform-support/nto-qnx.md | 11 ++++---- tests/assembly/targets/targets-elf.rs | 3 +++ 7 files changed, 41 insertions(+), 7 deletions(-) create mode 100644 compiler/rustc_target/src/spec/targets/x86_64_pc_nto_qnx710_iosock.rs diff --git a/compiler/rustc_target/src/spec/mod.rs b/compiler/rustc_target/src/spec/mod.rs index df6d117f3760..fdfc72b1bea6 100644 --- a/compiler/rustc_target/src/spec/mod.rs +++ b/compiler/rustc_target/src/spec/mod.rs @@ -1965,6 +1965,7 @@ supported_targets! { ("aarch64-unknown-nto-qnx710", aarch64_unknown_nto_qnx710), ("aarch64-unknown-nto-qnx710_iosock", aarch64_unknown_nto_qnx710_iosock), ("x86_64-pc-nto-qnx710", x86_64_pc_nto_qnx710), + ("x86_64-pc-nto-qnx710_iosock", x86_64_pc_nto_qnx710_iosock), ("i586-pc-nto-qnx700", i586_pc_nto_qnx700), ("aarch64-unknown-linux-ohos", aarch64_unknown_linux_ohos), diff --git a/compiler/rustc_target/src/spec/targets/x86_64_pc_nto_qnx710_iosock.rs b/compiler/rustc_target/src/spec/targets/x86_64_pc_nto_qnx710_iosock.rs new file mode 100644 index 000000000000..9a1035fd78ee --- /dev/null +++ b/compiler/rustc_target/src/spec/targets/x86_64_pc_nto_qnx710_iosock.rs @@ -0,0 +1,27 @@ +use crate::spec::{Cc, LinkerFlavor, Lld, Target, TargetOptions}; + +pub(crate) fn target() -> Target { + let mut target = super::x86_64_pc_nto_qnx710::target(); + target.options.env = "nto71_iosock".into(); + target.options.pre_link_args = + TargetOptions::link_args(LinkerFlavor::Gnu(Cc::Yes, Lld::No), &[ + "-Vgcc_ntox86_64_cxx", + get_iosock_param(), + ]); + target +} + +// When using `io-sock` on QNX, we must add a search path for the linker so +// that it prefers the io-sock version. +// The path depends on the host, i.e. we cannot hard-code it here, but have +// to determine it when the compiler runs. +// When using the QNX toolchain, the environment variable QNX_TARGET is always set. +// More information: +// https://www.qnx.com/developers/docs/7.1/index.html#com.qnx.doc.neutrino.io_sock/topic/migrate_app.html +fn get_iosock_param() -> &'static str { + let target_dir = + std::env::var("QNX_TARGET").unwrap_or_else(|_| "PLEASE_SET_ENV_VAR_QNX_TARGET".into()); + let linker_param = format!("-L{target_dir}/x86_64/io-sock/lib"); + + linker_param.leak() +} diff --git a/library/std/Cargo.toml b/library/std/Cargo.toml index b91b89b7761b..16e7cb5c3a8b 100644 --- a/library/std/Cargo.toml +++ b/library/std/Cargo.toml @@ -139,7 +139,7 @@ test = true level = "warn" check-cfg = [ 'cfg(bootstrap)', - 'cfg(target_arch, values("xtensa", "aarch64-unknown-nto-qnx710_iosock"))', + 'cfg(target_arch, values("xtensa", "aarch64-unknown-nto-qnx710_iosock", "x86_64-pc-nto-qnx710_iosock"))', 'cfg(target_env, values("nto71_iosock"))', # std use #[path] imports to portable-simd `std_float` crate # and to the `backtrace` crate which messes-up with Cargo list diff --git a/src/bootstrap/src/core/sanity.rs b/src/bootstrap/src/core/sanity.rs index 418ebbbfb42c..87d273abf17e 100644 --- a/src/bootstrap/src/core/sanity.rs +++ b/src/bootstrap/src/core/sanity.rs @@ -35,6 +35,7 @@ pub struct Finder { const STAGE0_MISSING_TARGETS: &[&str] = &[ // just a dummy comment so the list doesn't get onelined "aarch64-unknown-nto-qnx710_iosock", + "x86_64-pc-nto-qnx710_iosock", ]; /// Minimum version threshold for libstdc++ required when using prebuilt LLVM diff --git a/src/doc/rustc/src/platform-support.md b/src/doc/rustc/src/platform-support.md index d25eaa49dd5e..de950dbfbe0c 100644 --- a/src/doc/rustc/src/platform-support.md +++ b/src/doc/rustc/src/platform-support.md @@ -406,7 +406,8 @@ target | std | host | notes [`wasm64-unknown-unknown`](platform-support/wasm64-unknown-unknown.md) | ? | | WebAssembly [`x86_64-apple-tvos`](platform-support/apple-tvos.md) | ✓ | | x86 64-bit tvOS [`x86_64-apple-watchos-sim`](platform-support/apple-watchos.md) | ✓ | | x86 64-bit Apple WatchOS simulator -[`x86_64-pc-nto-qnx710`](platform-support/nto-qnx.md) | ✓ | | x86 64-bit QNX Neutrino 7.1 RTOS | +[`x86_64-pc-nto-qnx710`](platform-support/nto-qnx.md) | ✓ | | x86 64-bit QNX Neutrino 7.1 RTOS with default network stack (io-pkt) | +[`x86_64-pc-nto-qnx710_iosock`](platform-support/nto-qnx.md) | ✓ | | x86 64-bit QNX Neutrino 7.1 RTOS with new network stack (io-sock) | [`x86_64-unikraft-linux-musl`](platform-support/unikraft-linux-musl.md) | ✓ | | 64-bit Unikraft with musl 1.2.3 `x86_64-unknown-dragonfly` | ✓ | ✓ | 64-bit DragonFlyBSD `x86_64-unknown-haiku` | ✓ | ✓ | 64-bit Haiku diff --git a/src/doc/rustc/src/platform-support/nto-qnx.md b/src/doc/rustc/src/platform-support/nto-qnx.md index 7d6d9ff3223c..1bfd97b8f342 100644 --- a/src/doc/rustc/src/platform-support/nto-qnx.md +++ b/src/doc/rustc/src/platform-support/nto-qnx.md @@ -22,11 +22,12 @@ Currently, the following QNX Neutrino versions and compilation targets are suppo | QNX Neutrino Version | Target Architecture | Full support | `no_std` support | |----------------------|---------------------|:------------:|:----------------:| -| 7.1 with io-pkt | AArch64 | ✓ | ✓ | -| 7.1 with io-sock | AArch64 | ✓ | ✓ | -| 7.1 | x86_64 | ✓ | ✓ | -| 7.0 | AArch64 | ? | ✓ | -| 7.0 | x86 | | ✓ | +| 7.1 with io-pkt | AArch64 | ✓ | ✓ | +| 7.1 with io-sock | AArch64 | ? | ✓ | +| 7.1 with io-pkt | x86_64 | ✓ | ✓ | +| 7.1 with io-sock | x86_64 | ? | ✓ | +| 7.0 | AArch64 | ? | ✓ | +| 7.0 | x86 | | ✓ | On QNX 7.0 and 7.1, `io-pkt` is used as network stack by default. QNX 7.1 includes the optional network stack `io-sock`. diff --git a/tests/assembly/targets/targets-elf.rs b/tests/assembly/targets/targets-elf.rs index b9d6aaf7929b..9f2711880c79 100644 --- a/tests/assembly/targets/targets-elf.rs +++ b/tests/assembly/targets/targets-elf.rs @@ -567,6 +567,9 @@ //@ revisions: x86_64_pc_nto_qnx710 //@ [x86_64_pc_nto_qnx710] compile-flags: --target x86_64-pc-nto-qnx710 //@ [x86_64_pc_nto_qnx710] needs-llvm-components: x86 +//@ revisions: x86_64_pc_nto_qnx710_iosock +//@ [x86_64_pc_nto_qnx710_iosock] compile-flags: --target x86_64-pc-nto-qnx710_iosock +//@ [x86_64_pc_nto_qnx710_iosock] needs-llvm-components: x86 //@ revisions: x86_64_pc_solaris //@ [x86_64_pc_solaris] compile-flags: --target x86_64-pc-solaris //@ [x86_64_pc_solaris] needs-llvm-components: x86 From 62661f25921770fd973567e62836adf6e3246ac9 Mon Sep 17 00:00:00 2001 From: Florian Bartels Date: Sat, 30 Nov 2024 10:34:46 +0100 Subject: [PATCH 24/81] Move common code to mod nto_qnx Signed-off-by: Florian Bartels --- .../rustc_target/src/spec/base/nto_qnx.rs | 97 ++++++++++++++++++- .../targets/aarch64_unknown_nto_qnx700.rs | 42 ++------ .../targets/aarch64_unknown_nto_qnx710.rs | 12 ++- .../aarch64_unknown_nto_qnx710_iosock.rs | 29 ++---- .../src/spec/targets/i586_pc_nto_qnx700.rs | 20 ++-- .../src/spec/targets/x86_64_pc_nto_qnx710.rs | 34 ++----- .../targets/x86_64_pc_nto_qnx710_iosock.rs | 29 ++---- src/doc/rustc/src/platform-support/nto-qnx.md | 43 ++++---- 8 files changed, 169 insertions(+), 137 deletions(-) diff --git a/compiler/rustc_target/src/spec/base/nto_qnx.rs b/compiler/rustc_target/src/spec/base/nto_qnx.rs index 65475d068d7e..819e68a0500d 100644 --- a/compiler/rustc_target/src/spec/base/nto_qnx.rs +++ b/compiler/rustc_target/src/spec/base/nto_qnx.rs @@ -1,4 +1,6 @@ -use crate::spec::{RelroLevel, TargetOptions, cvs}; +use crate::spec::{ + Cc, LinkArgs, LinkerFlavor, Lld, RelroLevel, Target, TargetMetadata, TargetOptions, cvs, +}; pub(crate) fn opts() -> TargetOptions { TargetOptions { @@ -16,3 +18,96 @@ pub(crate) fn opts() -> TargetOptions { ..Default::default() } } + +pub(crate) fn meta() -> TargetMetadata { + TargetMetadata { description: None, tier: Some(3), host_tools: Some(false), std: Some(true) } +} + +pub(crate) fn aarch64() -> Target { + Target { + llvm_target: "aarch64-unknown-unknown".into(), + metadata: meta(), + pointer_width: 64, + // from: https://llvm.org/docs/LangRef.html#data-layout + // e = little endian + // m:e = ELF mangling: Private symbols get a .L prefix + // i8:8:32 = 8-bit-integer, minimum_alignment=8, preferred_alignment=32 + // i16:16:32 = 16-bit-integer, minimum_alignment=16, preferred_alignment=32 + // i64:64 = 64-bit-integer, minimum_alignment=64, preferred_alignment=64 + // i128:128 = 128-bit-integer, minimum_alignment=128, preferred_alignment=128 + // n32:64 = 32 and 64 are native integer widths; Elements of this set are considered to support most general arithmetic operations efficiently. + // S128 = 128 bits are the natural alignment of the stack in bits. + data_layout: "e-m:e-p270:32:32-p271:32:32-p272:64:64-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128-Fn32".into(), + arch: "aarch64".into(), + options: TargetOptions { + features: "+v8a".into(), + max_atomic_width: Some(128), + ..opts() + } + } +} + +pub(crate) fn x86_64() -> Target { + Target { + llvm_target: "x86_64-pc-unknown".into(), + metadata: meta(), + pointer_width: 64, + data_layout: + "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128".into(), + arch: "x86_64".into(), + options: TargetOptions { + cpu: "x86-64".into(), + plt_by_default: false, + max_atomic_width: Some(64), + vendor: "pc".into(), + ..opts() + }, + } +} + +pub(crate) fn pre_link_args(api_var: ApiVariant, arch: Arch) -> LinkArgs { + let (qcc_arg, arch_lib_dir) = match arch { + Arch::Aarch64 => ("-Vgcc_ntoaarch64le_cxx", "aarch64le"), + Arch::I586 => { + ("-Vgcc_ntox86_cxx", "notSupportedByQnx_compiler/rustc_target/src/spec/base/nto_qnx.rs") + } + Arch::X86_64 => ("-Vgcc_ntox86_64_cxx", "x86_64"), + }; + match api_var { + ApiVariant::Default => { + TargetOptions::link_args(LinkerFlavor::Gnu(Cc::Yes, Lld::No), &[qcc_arg]) + } + ApiVariant::IoSock => TargetOptions::link_args(LinkerFlavor::Gnu(Cc::Yes, Lld::No), &[ + qcc_arg, + get_iosock_param(arch_lib_dir), + ]), + } +} + +pub(crate) enum ApiVariant { + Default, + IoSock, +} + +pub(crate) enum Arch { + Aarch64, + I586, + X86_64, +} + +// When using `io-sock` on QNX, we must add a search path for the linker so +// that it prefers the io-sock version. +// The path depends on the host, i.e. we cannot hard-code it here, but have +// to determine it when the compiler runs. +// When using the QNX toolchain, the environment variable QNX_TARGET is always set. +// More information: +// https://www.qnx.com/developers/docs/7.1/index.html#com.qnx.doc.neutrino.io_sock/topic/migrate_app.html +fn get_iosock_param(arch_lib_dir: &str) -> &'static str { + let target_dir = std::env::var("QNX_TARGET") + .unwrap_or_else(|_| "QNX_TARGET_not_set_please_source_qnxsdp-env.sh".into()); + let linker_param = format!("-L{target_dir}/{arch_lib_dir}/io-sock/lib"); + + // FIXME: leaking this is kind of weird: we're feeding these into something that expects an + // `AsRef`, but often converts to `OsString` anyways, so shouldn't we just demand an `OsString`? + linker_param.leak() +} diff --git a/compiler/rustc_target/src/spec/targets/aarch64_unknown_nto_qnx700.rs b/compiler/rustc_target/src/spec/targets/aarch64_unknown_nto_qnx700.rs index 441ed7cf1535..b26e6f19e1ab 100644 --- a/compiler/rustc_target/src/spec/targets/aarch64_unknown_nto_qnx700.rs +++ b/compiler/rustc_target/src/spec/targets/aarch64_unknown_nto_qnx700.rs @@ -1,37 +1,11 @@ -use crate::spec::{Cc, LinkerFlavor, Lld, Target, TargetOptions, base}; +use crate::spec::Target; +use crate::spec::base::nto_qnx; pub(crate) fn target() -> Target { - // In QNX, libc does not provide a compatible ABI between versions. - // To distinguish between QNX versions, we needed a stable conditional compilation switch, - // which is why we needed to implement different targets in the compiler. - Target { - llvm_target: "aarch64-unknown-unknown".into(), - metadata: crate::spec::TargetMetadata { - description: Some("ARM64 QNX Neutrino 7.0 RTOS".into()), - tier: Some(3), - host_tools: Some(false), - std: Some(true), - }, - pointer_width: 64, - // from: https://llvm.org/docs/LangRef.html#data-layout - // e = little endian - // m:e = ELF mangling: Private symbols get a .L prefix - // i8:8:32 = 8-bit-integer, minimum_alignment=8, preferred_alignment=32 - // i16:16:32 = 16-bit-integer, minimum_alignment=16, preferred_alignment=32 - // i64:64 = 64-bit-integer, minimum_alignment=64, preferred_alignment=64 - // i128:128 = 128-bit-integer, minimum_alignment=128, preferred_alignment=128 - // n32:64 = 32 and 64 are native integer widths; Elements of this set are considered to support most general arithmetic operations efficiently. - // S128 = 128 bits are the natural alignment of the stack in bits. - data_layout: "e-m:e-p270:32:32-p271:32:32-p272:64:64-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128-Fn32".into(), - arch: "aarch64".into(), - options: TargetOptions { - features: "+v8a".into(), - max_atomic_width: Some(128), - pre_link_args: TargetOptions::link_args(LinkerFlavor::Gnu(Cc::Yes, Lld::No), &[ - "-Vgcc_ntoaarch64le_cxx", - ]), - env: "nto70".into(), - ..base::nto_qnx::opts() - }, - } + let mut target = nto_qnx::aarch64(); + target.metadata.description = Some("ARM64 QNX Neutrino 7.0 RTOS".into()); + target.options.pre_link_args = + nto_qnx::pre_link_args(nto_qnx::ApiVariant::Default, nto_qnx::Arch::Aarch64); + target.options.env = "nto70".into(); + target } diff --git a/compiler/rustc_target/src/spec/targets/aarch64_unknown_nto_qnx710.rs b/compiler/rustc_target/src/spec/targets/aarch64_unknown_nto_qnx710.rs index 5b5a21fca952..3a78952c36c4 100644 --- a/compiler/rustc_target/src/spec/targets/aarch64_unknown_nto_qnx710.rs +++ b/compiler/rustc_target/src/spec/targets/aarch64_unknown_nto_qnx710.rs @@ -1,8 +1,12 @@ use crate::spec::Target; +use crate::spec::base::nto_qnx; pub(crate) fn target() -> Target { - let mut base = super::aarch64_unknown_nto_qnx700::target(); - base.metadata.description = Some("ARM64 QNX Neutrino 7.1 RTOS".into()); - base.options.env = "nto71".into(); - base + let mut target = nto_qnx::aarch64(); + target.metadata.description = + Some("ARM64 QNX Neutrino 7.1 RTOS with io-pkt network stack".into()); + target.options.pre_link_args = + nto_qnx::pre_link_args(nto_qnx::ApiVariant::Default, nto_qnx::Arch::Aarch64); + target.options.env = "nto71".into(); + target } diff --git a/compiler/rustc_target/src/spec/targets/aarch64_unknown_nto_qnx710_iosock.rs b/compiler/rustc_target/src/spec/targets/aarch64_unknown_nto_qnx710_iosock.rs index c9ffc0e072c3..4964f4078f5c 100644 --- a/compiler/rustc_target/src/spec/targets/aarch64_unknown_nto_qnx710_iosock.rs +++ b/compiler/rustc_target/src/spec/targets/aarch64_unknown_nto_qnx710_iosock.rs @@ -1,27 +1,12 @@ -use crate::spec::{Cc, LinkerFlavor, Lld, Target, TargetOptions}; +use crate::spec::Target; +use crate::spec::base::nto_qnx; pub(crate) fn target() -> Target { - let mut target = super::aarch64_unknown_nto_qnx710::target(); - target.options.env = "nto71_iosock".into(); + let mut target = nto_qnx::aarch64(); + target.metadata.description = + Some("ARM64 QNX Neutrino 7.1 RTOS with io-sock network stack".into()); target.options.pre_link_args = - TargetOptions::link_args(LinkerFlavor::Gnu(Cc::Yes, Lld::No), &[ - "-Vgcc_ntoaarch64le_cxx", - get_iosock_param(), - ]); + nto_qnx::pre_link_args(nto_qnx::ApiVariant::IoSock, nto_qnx::Arch::Aarch64); + target.options.env = "nto71_iosock".into(); target } - -// When using `io-sock` on QNX, we must add a search path for the linker so -// that it prefers the io-sock version. -// The path depends on the host, i.e. we cannot hard-code it here, but have -// to determine it when the compiler runs. -// When using the QNX toolchain, the environment variable QNX_TARGET is always set. -// More information: -// https://www.qnx.com/developers/docs/7.1/index.html#com.qnx.doc.neutrino.io_sock/topic/migrate_app.html -fn get_iosock_param() -> &'static str { - let target_dir = - std::env::var("QNX_TARGET").unwrap_or_else(|_| "PLEASE_SET_ENV_VAR_QNX_TARGET".into()); - let linker_param = format!("-L{target_dir}/aarch64le/io-sock/lib"); - - linker_param.leak() -} diff --git a/compiler/rustc_target/src/spec/targets/i586_pc_nto_qnx700.rs b/compiler/rustc_target/src/spec/targets/i586_pc_nto_qnx700.rs index 7648f81fd4d9..fa21cfbab8a3 100644 --- a/compiler/rustc_target/src/spec/targets/i586_pc_nto_qnx700.rs +++ b/compiler/rustc_target/src/spec/targets/i586_pc_nto_qnx700.rs @@ -1,14 +1,13 @@ -use crate::spec::{Cc, LinkerFlavor, Lld, StackProbeType, Target, TargetOptions, base}; +use crate::spec::base::nto_qnx; +use crate::spec::{StackProbeType, Target, TargetOptions, base}; pub(crate) fn target() -> Target { + let mut meta = nto_qnx::meta(); + meta.description = Some("32-bit x86 QNX Neutrino 7.0 RTOS".into()); + meta.std = Some(false); Target { llvm_target: "i586-pc-unknown".into(), - metadata: crate::spec::TargetMetadata { - description: Some("32-bit x86 QNX Neutrino 7.0 RTOS".into()), - tier: Some(3), - host_tools: Some(false), - std: Some(false), - }, + metadata: meta, pointer_width: 32, data_layout: "e-m:e-p:32:32-p270:32:32-p271:32:32-p272:64:64-\ i128:128-f64:32:64-f80:32-n8:16:32-S128" @@ -17,9 +16,10 @@ pub(crate) fn target() -> Target { options: TargetOptions { cpu: "pentium4".into(), max_atomic_width: Some(64), - pre_link_args: TargetOptions::link_args(LinkerFlavor::Gnu(Cc::Yes, Lld::No), &[ - "-Vgcc_ntox86_cxx", - ]), + pre_link_args: nto_qnx::pre_link_args( + nto_qnx::ApiVariant::Default, + nto_qnx::Arch::I586, + ), env: "nto70".into(), vendor: "pc".into(), stack_probes: StackProbeType::Inline, diff --git a/compiler/rustc_target/src/spec/targets/x86_64_pc_nto_qnx710.rs b/compiler/rustc_target/src/spec/targets/x86_64_pc_nto_qnx710.rs index 245a5f067654..248aa91862c9 100644 --- a/compiler/rustc_target/src/spec/targets/x86_64_pc_nto_qnx710.rs +++ b/compiler/rustc_target/src/spec/targets/x86_64_pc_nto_qnx710.rs @@ -1,28 +1,12 @@ -use crate::spec::{Cc, LinkerFlavor, Lld, Target, TargetOptions, base}; +use crate::spec::Target; +use crate::spec::base::nto_qnx; pub(crate) fn target() -> Target { - Target { - llvm_target: "x86_64-pc-unknown".into(), - metadata: crate::spec::TargetMetadata { - description: Some("x86 64-bit QNX Neutrino 7.1 RTOS".into()), - tier: Some(3), - host_tools: Some(false), - std: Some(true), - }, - pointer_width: 64, - data_layout: - "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128".into(), - arch: "x86_64".into(), - options: TargetOptions { - cpu: "x86-64".into(), - plt_by_default: false, - max_atomic_width: Some(64), - pre_link_args: TargetOptions::link_args(LinkerFlavor::Gnu(Cc::Yes, Lld::No), &[ - "-Vgcc_ntox86_64_cxx", - ]), - env: "nto71".into(), - vendor: "pc".into(), - ..base::nto_qnx::opts() - }, - } + let mut target = nto_qnx::x86_64(); + target.metadata.description = + Some("x86 64-bit QNX Neutrino 7.1 RTOS with io-pkt network stack".into()); + target.options.pre_link_args = + nto_qnx::pre_link_args(nto_qnx::ApiVariant::Default, nto_qnx::Arch::X86_64); + target.options.env = "nto71".into(); + target } diff --git a/compiler/rustc_target/src/spec/targets/x86_64_pc_nto_qnx710_iosock.rs b/compiler/rustc_target/src/spec/targets/x86_64_pc_nto_qnx710_iosock.rs index 9a1035fd78ee..8f4c4924a295 100644 --- a/compiler/rustc_target/src/spec/targets/x86_64_pc_nto_qnx710_iosock.rs +++ b/compiler/rustc_target/src/spec/targets/x86_64_pc_nto_qnx710_iosock.rs @@ -1,27 +1,12 @@ -use crate::spec::{Cc, LinkerFlavor, Lld, Target, TargetOptions}; +use crate::spec::Target; +use crate::spec::base::nto_qnx; pub(crate) fn target() -> Target { - let mut target = super::x86_64_pc_nto_qnx710::target(); - target.options.env = "nto71_iosock".into(); + let mut target = nto_qnx::x86_64(); + target.metadata.description = + Some("x86 64-bit QNX Neutrino 7.1 RTOS with io-sock network stack".into()); target.options.pre_link_args = - TargetOptions::link_args(LinkerFlavor::Gnu(Cc::Yes, Lld::No), &[ - "-Vgcc_ntox86_64_cxx", - get_iosock_param(), - ]); + nto_qnx::pre_link_args(nto_qnx::ApiVariant::IoSock, nto_qnx::Arch::X86_64); + target.options.env = "nto71_iosock".into(); target } - -// When using `io-sock` on QNX, we must add a search path for the linker so -// that it prefers the io-sock version. -// The path depends on the host, i.e. we cannot hard-code it here, but have -// to determine it when the compiler runs. -// When using the QNX toolchain, the environment variable QNX_TARGET is always set. -// More information: -// https://www.qnx.com/developers/docs/7.1/index.html#com.qnx.doc.neutrino.io_sock/topic/migrate_app.html -fn get_iosock_param() -> &'static str { - let target_dir = - std::env::var("QNX_TARGET").unwrap_or_else(|_| "PLEASE_SET_ENV_VAR_QNX_TARGET".into()); - let linker_param = format!("-L{target_dir}/x86_64/io-sock/lib"); - - linker_param.leak() -} diff --git a/src/doc/rustc/src/platform-support/nto-qnx.md b/src/doc/rustc/src/platform-support/nto-qnx.md index 1bfd97b8f342..75f8cbad959e 100644 --- a/src/doc/rustc/src/platform-support/nto-qnx.md +++ b/src/doc/rustc/src/platform-support/nto-qnx.md @@ -136,18 +136,31 @@ To compile for QNX Neutrino (aarch64 and x86_64) and Linux (x86_64): ```bash export build_env=' - CC_aarch64-unknown-nto-qnx710=qcc - CFLAGS_aarch64-unknown-nto-qnx710=-Vgcc_ntoaarch64le_cxx - CXX_aarch64-unknown-nto-qnx710=qcc + CC_i586_pc_nto_qnx700=qcc + CFLAGS_i586_pc_nto_qnx700=-Vgcc_ntox86_cxx + CXX_i586_pc_nto_qnx700=qcc + AR_i586_pc_nto_qnx700=ntox86-ar + + CC_aarch64_unknown_nto_qnx710=qcc + CFLAGS_aarch64_unknown_nto_qnx710=-Vgcc_ntoaarch64le_cxx + CXX_aarch64_unknown_nto_qnx710=qcc AR_aarch64_unknown_nto_qnx710=ntoaarch64-ar - CC_aarch64-unknown-nto-qnx710_iosock=qcc - CFLAGS_aarch64-unknown-nto-qnx710_iosock=-Vgcc_ntoaarch64le_cxx - CXX_aarch64-unknown-nto-qnx710_iosock=qcc + + CC_aarch64_unknown_nto_qnx710_iosock=qcc + CFLAGS_aarch64_unknown_nto_qnx710_iosock=-Vgcc_ntoaarch64le_cxx + CXX_aarch64_unknown_nto_qnx710_iosock=qcc AR_aarch64_unknown_nto_qnx710_iosock=ntoaarch64-ar - CC_x86_64-pc-nto-qnx710=qcc - CFLAGS_x86_64-pc-nto-qnx710=-Vgcc_ntox86_64_cxx - CXX_x86_64-pc-nto-qnx710=qcc - AR_x86_64_pc_nto_qnx710=ntox86_64-ar' + + CC_aarch64_unknown_nto_qnx700=qcc + CFLAGS_aarch64_unknown_nto_qnx700=-Vgcc_ntoaarch64le_cxx + CXX_aarch64_unknown_nto_qnx700=qcc + AR_aarch64_unknown_nto_qnx700=ntoaarch64-ar + + CC_x86_64_pc_nto_qnx710=qcc + CFLAGS_x86_64_pc_nto_qnx710=-Vgcc_ntox86_64_cxx + CXX_x86_64_pc_nto_qnx710=qcc + AR_x86_64_pc_nto_qnx710=ntox86_64-ar + ' env $build_env \ ./x.py build \ @@ -167,15 +180,7 @@ To run all tests on a x86_64 QNX Neutrino target: ```bash export TEST_DEVICE_ADDR="localhost:12345" # must address the test target, can be a SSH tunnel -export build_env=' - CC_aarch64-unknown-nto-qnx710=qcc - CFLAGS_aarch64-unknown-nto-qnx710=-Vgcc_ntoaarch64le_cxx - CXX_aarch64-unknown-nto-qnx710=qcc - AR_aarch64_unknown_nto_qnx710=ntoaarch64-ar - CC_x86_64-pc-nto-qnx710=qcc - CFLAGS_x86_64-pc-nto-qnx710=-Vgcc_ntox86_64_cxx - CXX_x86_64-pc-nto-qnx710=qcc - AR_x86_64_pc_nto_qnx710=ntox86_64-ar' +export build_env= # Disable tests that only work on the host or don't make sense for this target. # See also: From 3f045c9d2e186402c135caf6cbc7fc8a41a684b6 Mon Sep 17 00:00:00 2001 From: AkhilTThomas Date: Fri, 6 Dec 2024 11:38:25 +0100 Subject: [PATCH 25/81] add nto80 x86-64 and aarch64 target Signed-off-by: Florian Bartels --- compiler/rustc_target/src/spec/mod.rs | 2 ++ .../src/spec/targets/aarch64_unknown_nto_qnx800.rs | 11 +++++++++++ .../src/spec/targets/x86_64_pc_nto_qnx800.rs | 11 +++++++++++ library/std/Cargo.toml | 4 ++-- .../std/src/sys/pal/unix/process/process_unix.rs | 14 +++----------- src/bootstrap/src/core/sanity.rs | 2 ++ src/doc/rustc/src/platform-support/nto-qnx.md | 1 + tests/assembly/targets/targets-elf.rs | 6 ++++++ tests/ui/check-cfg/well-known-values.stderr | 2 +- 9 files changed, 39 insertions(+), 14 deletions(-) create mode 100644 compiler/rustc_target/src/spec/targets/aarch64_unknown_nto_qnx800.rs create mode 100644 compiler/rustc_target/src/spec/targets/x86_64_pc_nto_qnx800.rs diff --git a/compiler/rustc_target/src/spec/mod.rs b/compiler/rustc_target/src/spec/mod.rs index fdfc72b1bea6..bcd2aff54bb1 100644 --- a/compiler/rustc_target/src/spec/mod.rs +++ b/compiler/rustc_target/src/spec/mod.rs @@ -1964,8 +1964,10 @@ supported_targets! { ("aarch64-unknown-nto-qnx700", aarch64_unknown_nto_qnx700), ("aarch64-unknown-nto-qnx710", aarch64_unknown_nto_qnx710), ("aarch64-unknown-nto-qnx710_iosock", aarch64_unknown_nto_qnx710_iosock), + ("aarch64-unknown-nto-qnx800", aarch64_unknown_nto_qnx800), ("x86_64-pc-nto-qnx710", x86_64_pc_nto_qnx710), ("x86_64-pc-nto-qnx710_iosock", x86_64_pc_nto_qnx710_iosock), + ("x86_64-pc-nto-qnx800", x86_64_pc_nto_qnx800), ("i586-pc-nto-qnx700", i586_pc_nto_qnx700), ("aarch64-unknown-linux-ohos", aarch64_unknown_linux_ohos), diff --git a/compiler/rustc_target/src/spec/targets/aarch64_unknown_nto_qnx800.rs b/compiler/rustc_target/src/spec/targets/aarch64_unknown_nto_qnx800.rs new file mode 100644 index 000000000000..5b820681efe9 --- /dev/null +++ b/compiler/rustc_target/src/spec/targets/aarch64_unknown_nto_qnx800.rs @@ -0,0 +1,11 @@ +use crate::spec::Target; +use crate::spec::base::nto_qnx; + +pub(crate) fn target() -> Target { + let mut target = nto_qnx::aarch64(); + target.metadata.description = Some("ARM64 QNX Neutrino 8.0 RTOS".into()); + target.options.pre_link_args = + nto_qnx::pre_link_args(nto_qnx::ApiVariant::Default, nto_qnx::Arch::Aarch64); + target.options.env = "nto80".into(); + target +} diff --git a/compiler/rustc_target/src/spec/targets/x86_64_pc_nto_qnx800.rs b/compiler/rustc_target/src/spec/targets/x86_64_pc_nto_qnx800.rs new file mode 100644 index 000000000000..d91a94a2ba55 --- /dev/null +++ b/compiler/rustc_target/src/spec/targets/x86_64_pc_nto_qnx800.rs @@ -0,0 +1,11 @@ +use crate::spec::Target; +use crate::spec::base::nto_qnx; + +pub(crate) fn target() -> Target { + let mut target = nto_qnx::x86_64(); + target.metadata.description = Some("x86 64-bit QNX Neutrino 8.0 RTOS".into()); + target.options.pre_link_args = + nto_qnx::pre_link_args(nto_qnx::ApiVariant::Default, nto_qnx::Arch::X86_64); + target.options.env = "nto80".into(); + target +} diff --git a/library/std/Cargo.toml b/library/std/Cargo.toml index 16e7cb5c3a8b..9eab75b06961 100644 --- a/library/std/Cargo.toml +++ b/library/std/Cargo.toml @@ -139,8 +139,8 @@ test = true level = "warn" check-cfg = [ 'cfg(bootstrap)', - 'cfg(target_arch, values("xtensa", "aarch64-unknown-nto-qnx710_iosock", "x86_64-pc-nto-qnx710_iosock"))', - 'cfg(target_env, values("nto71_iosock"))', + 'cfg(target_arch, values("xtensa", "aarch64-unknown-nto-qnx710_iosock", "x86_64-pc-nto-qnx710_iosock", "x86_64-pc-nto-qnx800","aarch64-unknown-nto-qnx800"))', + 'cfg(target_env, values("nto71_iosock", "nto80"))', # std use #[path] imports to portable-simd `std_float` crate # and to the `backtrace` crate which messes-up with Cargo list # of declared features, we therefor expect any feature cfg diff --git a/library/std/src/sys/pal/unix/process/process_unix.rs b/library/std/src/sys/pal/unix/process/process_unix.rs index cc22b3ecbd0f..2bff192a5bd8 100644 --- a/library/std/src/sys/pal/unix/process/process_unix.rs +++ b/library/std/src/sys/pal/unix/process/process_unix.rs @@ -19,8 +19,7 @@ use crate::sys::process::process_common::*; use crate::{fmt, mem, sys}; cfg_if::cfg_if! { - // This workaround is only needed for QNX 7.0 and 7.1. The bug should have been fixed in 8.0 - if #[cfg(any(target_env = "nto70", target_env = "nto71", target_env = "nto71_iosock"))] { + if #[cfg(target_os = "nto")] { use crate::thread; use libc::{c_char, posix_spawn_file_actions_t, posix_spawnattr_t}; use crate::time::Duration; @@ -187,13 +186,7 @@ impl Command { // Attempts to fork the process. If successful, returns Ok((0, -1)) // in the child, and Ok((child_pid, -1)) in the parent. - #[cfg(not(any( - target_os = "watchos", - target_os = "tvos", - target_env = "nto70", - target_env = "nto71", - target_env = "nto71_iosock", - )))] + #[cfg(not(any(target_os = "watchos", target_os = "tvos", target_os = "nto")))] unsafe fn do_fork(&mut self) -> Result { cvt(libc::fork()) } @@ -202,8 +195,7 @@ impl Command { // or closed a file descriptor while the fork() was occurring". // Documentation says "... or try calling fork() again". This is what we do here. // See also https://www.qnx.com/developers/docs/7.1/#com.qnx.doc.neutrino.lib_ref/topic/f/fork.html - // This workaround is only needed for QNX 7.0 and 7.1. The bug should have been fixed in 8.0 - #[cfg(any(target_env = "nto70", target_env = "nto71", target_env = "nto71_iosock"))] + #[cfg(target_os = "nto")] unsafe fn do_fork(&mut self) -> Result { use crate::sys::os::errno; diff --git a/src/bootstrap/src/core/sanity.rs b/src/bootstrap/src/core/sanity.rs index 87d273abf17e..6c8cda18548e 100644 --- a/src/bootstrap/src/core/sanity.rs +++ b/src/bootstrap/src/core/sanity.rs @@ -36,6 +36,8 @@ const STAGE0_MISSING_TARGETS: &[&str] = &[ // just a dummy comment so the list doesn't get onelined "aarch64-unknown-nto-qnx710_iosock", "x86_64-pc-nto-qnx710_iosock", + "x86_64-pc-nto-qnx800", + "aarch64-unknown-nto-qnx800", ]; /// Minimum version threshold for libstdc++ required when using prebuilt LLVM diff --git a/src/doc/rustc/src/platform-support/nto-qnx.md b/src/doc/rustc/src/platform-support/nto-qnx.md index 75f8cbad959e..4c4bd0494feb 100644 --- a/src/doc/rustc/src/platform-support/nto-qnx.md +++ b/src/doc/rustc/src/platform-support/nto-qnx.md @@ -115,6 +115,7 @@ For conditional compilation, following QNX Neutrino specific attributes are defi - `target_env` = `"nto71"` (for QNX Neutrino 7.1 with "classic" network stack "io_pkt") - `target_env` = `"nto71_iosock"` (for QNX Neutrino 7.1 with network stack "io_sock") - `target_env` = `"nto70"` (for QNX Neutrino 7.0) +- `target_env` = `"nto80"` (for QNX Neutrino 8.0) ## Building the target diff --git a/tests/assembly/targets/targets-elf.rs b/tests/assembly/targets/targets-elf.rs index 9f2711880c79..0ff886653a47 100644 --- a/tests/assembly/targets/targets-elf.rs +++ b/tests/assembly/targets/targets-elf.rs @@ -60,6 +60,9 @@ //@ revisions: aarch64_unknown_nto_qnx710_iosock //@ [aarch64_unknown_nto_qnx710_iosock] compile-flags: --target aarch64-unknown-nto-qnx710_iosock //@ [aarch64_unknown_nto_qnx710_iosock] needs-llvm-components: aarch64 +//@ revisions: aarch64_unknown_nto_qnx800 +//@ [aarch64_unknown_nto_qnx800] compile-flags: --target aarch64-unknown-nto-qnx800 +//@ [aarch64_unknown_nto_qnx800] needs-llvm-components: aarch64 //@ revisions: aarch64_unknown_openbsd //@ [aarch64_unknown_openbsd] compile-flags: --target aarch64-unknown-openbsd //@ [aarch64_unknown_openbsd] needs-llvm-components: aarch64 @@ -570,6 +573,9 @@ //@ revisions: x86_64_pc_nto_qnx710_iosock //@ [x86_64_pc_nto_qnx710_iosock] compile-flags: --target x86_64-pc-nto-qnx710_iosock //@ [x86_64_pc_nto_qnx710_iosock] needs-llvm-components: x86 +//@ revisions: x86_64_pc_nto_qnx800 +//@ [x86_64_pc_nto_qnx800] compile-flags: --target x86_64-pc-nto-qnx800 +//@ [x86_64_pc_nto_qnx800] needs-llvm-components: x86 //@ revisions: x86_64_pc_solaris //@ [x86_64_pc_solaris] compile-flags: --target x86_64-pc-solaris //@ [x86_64_pc_solaris] needs-llvm-components: x86 diff --git a/tests/ui/check-cfg/well-known-values.stderr b/tests/ui/check-cfg/well-known-values.stderr index 29bc30815b87..8ac3cb7ac3c2 100644 --- a/tests/ui/check-cfg/well-known-values.stderr +++ b/tests/ui/check-cfg/well-known-values.stderr @@ -156,7 +156,7 @@ warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE` LL | target_env = "_UNEXPECTED_VALUE", | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = note: expected values for `target_env` are: ``, `gnu`, `msvc`, `musl`, `newlib`, `nto70`, `nto71`, `nto71_iosock`, `ohos`, `p1`, `p2`, `relibc`, `sgx`, and `uclibc` + = note: expected values for `target_env` are: ``, `gnu`, `msvc`, `musl`, `newlib`, `nto70`, `nto71`, `nto71_iosock`, `nto80`, `ohos`, `p1`, `p2`, `relibc`, `sgx`, and `uclibc` = note: see for more information about checking conditional configuration warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE` From 46a03338fbadc7652425f0018a94f115ae173455 Mon Sep 17 00:00:00 2001 From: Florian Bartels Date: Tue, 10 Dec 2024 08:14:59 +0100 Subject: [PATCH 26/81] Update documentation to include QNX 8.0 Signed-off-by: Florian Bartels --- src/doc/rustc/src/platform-support.md | 7 +- src/doc/rustc/src/platform-support/nto-qnx.md | 80 ++++++++++--------- 2 files changed, 47 insertions(+), 40 deletions(-) diff --git a/src/doc/rustc/src/platform-support.md b/src/doc/rustc/src/platform-support.md index de950dbfbe0c..c964c29768f9 100644 --- a/src/doc/rustc/src/platform-support.md +++ b/src/doc/rustc/src/platform-support.md @@ -254,14 +254,14 @@ target | std | host | notes [`aarch64-kmc-solid_asp3`](platform-support/kmc-solid.md) | ✓ | | ARM64 SOLID with TOPPERS/ASP3 [`aarch64-nintendo-switch-freestanding`](platform-support/aarch64-nintendo-switch-freestanding.md) | * | | ARM64 Nintendo Switch, Horizon [`aarch64-unknown-freebsd`](platform-support/freebsd.md) | ✓ | ✓ | ARM64 FreeBSD -`aarch64-unknown-freebsd` | ✓ | ✓ | ARM64 FreeBSD [`aarch64-unknown-hermit`](platform-support/hermit.md) | ✓ | | ARM64 Hermit [`aarch64-unknown-illumos`](platform-support/illumos.md) | ✓ | ✓ | ARM64 illumos `aarch64-unknown-linux-gnu_ilp32` | ✓ | ✓ | ARM64 Linux (ILP32 ABI) [`aarch64-unknown-netbsd`](platform-support/netbsd.md) | ✓ | ✓ | ARM64 NetBSD -[`aarch64-unknown-nto-qnx710_iosock`](platform-support/nto-qnx.md) | ✓ | | ARM64 QNX Neutrino 7.1 RTOS with new network stack (io-sock) | -[`aarch64-unknown-nto-qnx710`](platform-support/nto-qnx.md) | ✓ | | ARM64 QNX Neutrino 7.1 RTOS | +[`aarch64-unknown-nto-qnx700`](platform-support/nto-qnx.md) | ? | | ARM64 QNX Neutrino 7.0 RTOS | [`aarch64-unknown-nto-qnx710`](platform-support/nto-qnx.md) | ✓ | | ARM64 QNX Neutrino 7.1 RTOS with default network stack (io-pkt) | +[`aarch64-unknown-nto-qnx710_iosock`](platform-support/nto-qnx.md) | ✓ | | ARM64 QNX Neutrino 7.1 RTOS with new network stack (io-sock) | +[`aarch64-unknown-nto-qnx800`](platform-support/nto-qnx.md) | ✓ | | ARM64 QNX Neutrino 8.0 RTOS | [`aarch64-unknown-nuttx`](platform-support/nuttx.md) | * | | ARM64 with NuttX [`aarch64-unknown-openbsd`](platform-support/openbsd.md) | ✓ | ✓ | ARM64 OpenBSD [`aarch64-unknown-redox`](platform-support/redox.md) | ✓ | | ARM64 Redox OS @@ -408,6 +408,7 @@ target | std | host | notes [`x86_64-apple-watchos-sim`](platform-support/apple-watchos.md) | ✓ | | x86 64-bit Apple WatchOS simulator [`x86_64-pc-nto-qnx710`](platform-support/nto-qnx.md) | ✓ | | x86 64-bit QNX Neutrino 7.1 RTOS with default network stack (io-pkt) | [`x86_64-pc-nto-qnx710_iosock`](platform-support/nto-qnx.md) | ✓ | | x86 64-bit QNX Neutrino 7.1 RTOS with new network stack (io-sock) | +[`x86_64-pc-nto-qnx800`](platform-support/nto-qnx.md) | ✓ | | x86 64-bit QNX Neutrino 8.0 RTOS | [`x86_64-unikraft-linux-musl`](platform-support/unikraft-linux-musl.md) | ✓ | | 64-bit Unikraft with musl 1.2.3 `x86_64-unknown-dragonfly` | ✓ | ✓ | 64-bit DragonFlyBSD `x86_64-unknown-haiku` | ✓ | ✓ | 64-bit Haiku diff --git a/src/doc/rustc/src/platform-support/nto-qnx.md b/src/doc/rustc/src/platform-support/nto-qnx.md index 4c4bd0494feb..4ac77f804497 100644 --- a/src/doc/rustc/src/platform-support/nto-qnx.md +++ b/src/doc/rustc/src/platform-support/nto-qnx.md @@ -22,6 +22,8 @@ Currently, the following QNX Neutrino versions and compilation targets are suppo | QNX Neutrino Version | Target Architecture | Full support | `no_std` support | |----------------------|---------------------|:------------:|:----------------:| +| 8.0 | AArch64 | ? | ✓ | +| 8.0 | x86 | ? | ✓ | | 7.1 with io-pkt | AArch64 | ✓ | ✓ | | 7.1 with io-sock | AArch64 | ? | ✓ | | 7.1 with io-pkt | x86_64 | ✓ | ✓ | @@ -31,6 +33,8 @@ Currently, the following QNX Neutrino versions and compilation targets are suppo On QNX 7.0 and 7.1, `io-pkt` is used as network stack by default. QNX 7.1 includes the optional network stack `io-sock`. +QNX 8.0 always uses `io-sock`. QNX 8.0 support is currently in development +and not tested. Adding other architectures that are supported by QNX Neutrino is possible. @@ -121,53 +125,55 @@ For conditional compilation, following QNX Neutrino specific attributes are defi 1. Create a `config.toml` -Example content: + Example content: -```toml -profile = "compiler" -change-id = 115898 -``` + ```toml + profile = "compiler" + change-id = 999999 + ``` -2. Compile the Rust toolchain for an `x86_64-unknown-linux-gnu` host (for both `aarch64` and `x86_64` targets) +2. Compile the Rust toolchain for an `x86_64-unknown-linux-gnu` host -Compiling the Rust toolchain requires the same environment variables used for compiling C binaries. -Refer to the [QNX developer manual](https://www.qnx.com/developers/docs/7.1/#com.qnx.doc.neutrino.prog/topic/devel_OS_version.html). + Compiling the Rust toolchain requires the same environment variables used for compiling C binaries. + Refer to the [QNX developer manual](https://www.qnx.com/developers/docs/7.1/#com.qnx.doc.neutrino.prog/topic/devel_OS_version.html). -To compile for QNX Neutrino (aarch64 and x86_64) and Linux (x86_64): + To compile for QNX Neutrino, environment variables must be set to use the correct tools and compiler switches: -```bash -export build_env=' - CC_i586_pc_nto_qnx700=qcc - CFLAGS_i586_pc_nto_qnx700=-Vgcc_ntox86_cxx - CXX_i586_pc_nto_qnx700=qcc - AR_i586_pc_nto_qnx700=ntox86-ar + - `CC_=qcc` + - `CFLAGS_=` + - `CXX_=qcc` + - `AR_=` - CC_aarch64_unknown_nto_qnx710=qcc - CFLAGS_aarch64_unknown_nto_qnx710=-Vgcc_ntoaarch64le_cxx - CXX_aarch64_unknown_nto_qnx710=qcc - AR_aarch64_unknown_nto_qnx710=ntoaarch64-ar + With: - CC_aarch64_unknown_nto_qnx710_iosock=qcc - CFLAGS_aarch64_unknown_nto_qnx710_iosock=-Vgcc_ntoaarch64le_cxx - CXX_aarch64_unknown_nto_qnx710_iosock=qcc - AR_aarch64_unknown_nto_qnx710_iosock=ntoaarch64-ar + - `` target triplet using underscores instead of hyphens, e.g. `aarch64_unknown_nto_qnx710` + - `` - CC_aarch64_unknown_nto_qnx700=qcc - CFLAGS_aarch64_unknown_nto_qnx700=-Vgcc_ntoaarch64le_cxx - CXX_aarch64_unknown_nto_qnx700=qcc - AR_aarch64_unknown_nto_qnx700=ntoaarch64-ar + - `-Vgcc_ntox86_cxx` for x86 (32 bit) + - `-Vgcc_ntox86_64_cxx` for x86_64 (64 bit) + - `-Vgcc_ntoaarch64le_cxx` for Aarch64 (64 bit) - CC_x86_64_pc_nto_qnx710=qcc - CFLAGS_x86_64_pc_nto_qnx710=-Vgcc_ntox86_64_cxx - CXX_x86_64_pc_nto_qnx710=qcc - AR_x86_64_pc_nto_qnx710=ntox86_64-ar - ' + - `` -env $build_env \ - ./x.py build \ - --target aarch64-unknown-nto-qnx710_iosock,aarch64-unknown-nto-qnx710,x86_64-pc-nto-qnx710,x86_64-unknown-linux-gnu \ - rustc library/core library/alloc library/std -``` + - `ntox86-ar` for x86 (32 bit) + - `ntox86_64-ar` for x86_64 (64 bit) + - `ntoaarch64-ar` for Aarch64 (64 bit) + + Example to build the Rust toolchain including a standard library for x86_64-linux-gnu and Aarch64-QNX-7.1: + + ```bash + export build_env=' + CC_aarch64_unknown_nto_qnx710=qcc + CFLAGS_aarch64_unknown_nto_qnx710=-Vgcc_ntoaarch64le_cxx + CXX_aarch64_unknown_nto_qnx710=qcc + AR_aarch64_unknown_nto_qnx710=ntoaarch64-ar + ' + + env $build_env \ + ./x.py build \ + --target x86_64-unknown-linux-gnu,aarch64-unknown-nto-qnx710 \ + rustc library/core library/alloc library/std + ``` ## Running the Rust test suite From 04628266c377b560afbceca5a1ba263bb2f5d162 Mon Sep 17 00:00:00 2001 From: Jonathan Pallant Date: Mon, 13 Jan 2025 14:56:01 +0000 Subject: [PATCH 27/81] Review nto-qnx.md. QNX SDP 8.0 comes with newly renamed QNX OS 8.0, so update the page to talk about QNX, QNX Neutrino 7.0, QNX Neutrino 7.1 or QNX OS 8.0. Also actually add a list of target triples. --- src/doc/rustc/src/platform-support/nto-qnx.md | 59 ++++++++++--------- 1 file changed, 30 insertions(+), 29 deletions(-) diff --git a/src/doc/rustc/src/platform-support/nto-qnx.md b/src/doc/rustc/src/platform-support/nto-qnx.md index 4ac77f804497..339741f14727 100644 --- a/src/doc/rustc/src/platform-support/nto-qnx.md +++ b/src/doc/rustc/src/platform-support/nto-qnx.md @@ -2,11 +2,13 @@ **Tier: 3** -[QNX®][BlackBerry] Neutrino (nto) Real-time operating system. -The support has been implemented jointly by [Elektrobit Automotive GmbH][Elektrobit] -and [Blackberry QNX][BlackBerry]. +The [QNX®][qnx.com] Neutrino (nto) Real-time operating system. Known as QNX OS +from version 8 onwards. -[BlackBerry]: https://blackberry.qnx.com +This support has been implemented jointly by [Elektrobit Automotive GmbH][Elektrobit] +and [QNX][qnx.com]. + +[qnx.com]: https://blackberry.qnx.com [Elektrobit]: https://www.elektrobit.com ## Target maintainers @@ -18,30 +20,29 @@ and [Blackberry QNX][BlackBerry]. ## Requirements -Currently, the following QNX Neutrino versions and compilation targets are supported: +Currently, the following QNX versions and compilation targets are supported: -| QNX Neutrino Version | Target Architecture | Full support | `no_std` support | -|----------------------|---------------------|:------------:|:----------------:| -| 8.0 | AArch64 | ? | ✓ | -| 8.0 | x86 | ? | ✓ | -| 7.1 with io-pkt | AArch64 | ✓ | ✓ | -| 7.1 with io-sock | AArch64 | ? | ✓ | -| 7.1 with io-pkt | x86_64 | ✓ | ✓ | -| 7.1 with io-sock | x86_64 | ? | ✓ | -| 7.0 | AArch64 | ? | ✓ | -| 7.0 | x86 | | ✓ | +| Target Tuple | QNX Version | Target Architecture | Full support | `no_std` support | +| ----------------------------------- | ----------------------------- | ------------------- | :----------: | :--------------: | +| `aarch64-unknown-nto-qnx800` | QNX OS 8.0 | AArch64 | ? | ✓ | +| `x86_64-pc-nto-qnx800` | QNX OS 8.0 | x86_64 | ? | ✓ | +| `aarch64-unknown-nto-qnx710` | QNX Neutrino 7.1 with io-pkt | AArch64 | ✓ | ✓ | +| `x86_64-pc-nto-qnx710` | QNX Neutrino 7.1 with io-pkt | x86_64 | ✓ | ✓ | +| `aarch64-unknown-nto-qnx710_iosock` | QNX Neutrino 7.1 with io-sock | AArch64 | ? | ✓ | +| `x86_64-pc-nto-qnx710_iosock` | QNX Neutrino 7.1 with io-sock | x86_64 | ? | ✓ | +| `aarch64-unknown-nto-qnx700` | QNX Neutrino 7.0 | AArch64 | ? | ✓ | +| `i586-pc-nto-qnx700` | QNX Neutrino 7.0 | x86 | | ✓ | -On QNX 7.0 and 7.1, `io-pkt` is used as network stack by default. QNX 7.1 includes -the optional network stack `io-sock`. -QNX 8.0 always uses `io-sock`. QNX 8.0 support is currently in development -and not tested. +On QNX Neutrino 7.0 and 7.1, `io-pkt` is used as network stack by default. +QNX Neutrino 7.1 includes the optional network stack `io-sock`. +QNX OS 8.0 always uses `io-sock`. QNX OS 8.0 support is currently work in progress. -Adding other architectures that are supported by QNX Neutrino is possible. +Adding other architectures that are supported by QNX is possible. -In the table above, 'full support' indicates support for building Rust applications with the full standard library. -'`no_std` support' indicates that only `core` and `alloc` are available. +In the table above, 'full support' indicates support for building Rust applications with the full standard library. A '?' means that support is in-progress. +'`no_std` support' is for building `#![no_std]` applications where only `core` and `alloc` are available. -For building or using the Rust toolchain for QNX Neutrino, the +For building or using the Rust toolchain for QNX, the [QNX Software Development Platform (SDP)](https://blackberry.qnx.com/en/products/foundation-software/qnx-software-development-platform) must be installed and initialized. Initialization is usually done by sourcing `qnxsdp-env.sh` (this will be installed as part of the SDP, see also installation instruction provided with the SDP). @@ -107,19 +108,19 @@ fn panic(_panic: &PanicInfo<'_>) -> ! { pub extern "C" fn rust_eh_personality() {} ``` -The QNX Neutrino support of Rust has been tested with QNX Neutrino 7.0 and 7.1. +The QNX support in Rust has been tested with QNX Neutrino 7.0 and 7.1. Support for QNX OS 8.0 is a work in progress. There are no further known requirements. ## Conditional compilation -For conditional compilation, following QNX Neutrino specific attributes are defined: +For conditional compilation, following QNX specific attributes are defined: - `target_os` = `"nto"` - `target_env` = `"nto71"` (for QNX Neutrino 7.1 with "classic" network stack "io_pkt") - `target_env` = `"nto71_iosock"` (for QNX Neutrino 7.1 with network stack "io_sock") - `target_env` = `"nto70"` (for QNX Neutrino 7.0) -- `target_env` = `"nto80"` (for QNX Neutrino 8.0) +- `target_env` = `"nto80"` (for QNX OS 8.0) ## Building the target @@ -137,7 +138,7 @@ For conditional compilation, following QNX Neutrino specific attributes are defi Compiling the Rust toolchain requires the same environment variables used for compiling C binaries. Refer to the [QNX developer manual](https://www.qnx.com/developers/docs/7.1/#com.qnx.doc.neutrino.prog/topic/devel_OS_version.html). - To compile for QNX Neutrino, environment variables must be set to use the correct tools and compiler switches: + To compile for QNX, environment variables must be set to use the correct tools and compiler switches: - `CC_=qcc` - `CFLAGS_=` @@ -183,7 +184,7 @@ addition of the TEST_DEVICE_ADDR environment variable. The TEST_DEVICE_ADDR variable controls the remote runner and should point to the target, despite localhost being shown in the following example. Note that some tests are failing which is why they are currently excluded by the target maintainers which can be seen in the following example. -To run all tests on a x86_64 QNX Neutrino target: +To run all tests on a x86_64 QNX Neutrino 7.1 target: ```bash export TEST_DEVICE_ADDR="localhost:12345" # must address the test target, can be a SSH tunnel @@ -217,7 +218,7 @@ or build your own copy of `core` by using `build-std` or similar. ## Testing -Compiled executables can run directly on QNX Neutrino. +Compiled executables can run directly on QNX. ### Rust std library test suite From 8d0eb87d08ac146cddb85e8f59fa6902204290c1 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Fri, 24 Jan 2025 15:28:16 +0100 Subject: [PATCH 28/81] Remove extra whitespace at the end of some line strings --- build_system/src/main.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/build_system/src/main.rs b/build_system/src/main.rs index 3a860e2b1360..393617183061 100644 --- a/build_system/src/main.rs +++ b/build_system/src/main.rs @@ -34,11 +34,11 @@ Options: --help : Displays this help message. Commands: - cargo : Executes a cargo command. + cargo : Executes a cargo command. rustc : Compiles the program using the GCC compiler. clean : Cleans the build directory, removing all compiled files and artifacts. prepare : Prepares the environment for building, including fetching dependencies and setting up configurations. - build : Compiles the project. + build : Compiles the project. test : Runs tests for the project. info : Displays information about the build environment and project configuration. clone-gcc : Clones the GCC compiler from a specified source. From 815be937ab5a3baaa726090cfb57feb90f7c95f9 Mon Sep 17 00:00:00 2001 From: Yotam Ofek Date: Thu, 23 Jan 2025 18:48:16 +0000 Subject: [PATCH 29/81] rustc_hir: replace `debug_fn` with unstable `fmt::from_fn` --- compiler/rustc_hir/src/hir.rs | 24 +++++++----------------- compiler/rustc_hir/src/lib.rs | 1 + 2 files changed, 8 insertions(+), 17 deletions(-) diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs index 5075ed86a6aa..a396d705cbb6 100644 --- a/compiler/rustc_hir/src/hir.rs +++ b/compiler/rustc_hir/src/hir.rs @@ -1285,13 +1285,13 @@ impl fmt::Debug for OwnerNodes<'_> { .field("node", &self.nodes[ItemLocalId::ZERO]) .field( "parents", - &self - .nodes - .iter_enumerated() - .map(|(id, parented_node)| { - debug_fn(move |f| write!(f, "({id:?}, {:?})", parented_node.parent)) - }) - .collect::>(), + &fmt::from_fn(|f| { + f.debug_list() + .entries(self.nodes.iter_enumerated().map(|(id, parented_node)| { + fmt::from_fn(move |f| write!(f, "({id:?}, {:?})", parented_node.parent)) + })) + .finish() + }), ) .field("bodies", &self.bodies) .field("opt_hash_including_bodies", &self.opt_hash_including_bodies) @@ -4638,15 +4638,5 @@ mod size_asserts { // tidy-alphabetical-end } -fn debug_fn(f: impl Fn(&mut fmt::Formatter<'_>) -> fmt::Result) -> impl fmt::Debug { - struct DebugFn(F); - impl) -> fmt::Result> fmt::Debug for DebugFn { - fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { - (self.0)(fmt) - } - } - DebugFn(f) -} - #[cfg(test)] mod tests; diff --git a/compiler/rustc_hir/src/lib.rs b/compiler/rustc_hir/src/lib.rs index 8ec2054bf53a..705c167e258c 100644 --- a/compiler/rustc_hir/src/lib.rs +++ b/compiler/rustc_hir/src/lib.rs @@ -6,6 +6,7 @@ #![allow(internal_features)] #![feature(associated_type_defaults)] #![feature(closure_track_caller)] +#![feature(debug_closure_helpers)] #![feature(exhaustive_patterns)] #![feature(let_chains)] #![feature(never_type)] From 8b57fd9e43baa9d8e1c72c54201d4820661f32c4 Mon Sep 17 00:00:00 2001 From: Yotam Ofek Date: Thu, 23 Jan 2025 19:48:54 +0000 Subject: [PATCH 30/81] use `fmt::from_fn` in more places, instead of using structs that impl formatting traits --- .../src/collect/resolve_bound_vars.rs | 92 +++++++++---------- compiler/rustc_hir_analysis/src/lib.rs | 1 + compiler/rustc_middle/src/lib.rs | 1 + compiler/rustc_middle/src/mir/query.rs | 68 ++++---------- compiler/rustc_middle/src/ty/context.rs | 76 +++++++-------- compiler/rustc_parse/src/parser/mod.rs | 60 +++++------- 6 files changed, 124 insertions(+), 174 deletions(-) diff --git a/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs b/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs index 582a2c7a0fc4..72baf5c4b58d 100644 --- a/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs +++ b/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs @@ -184,6 +184,50 @@ enum Scope<'a> { }, } +impl<'a> Scope<'a> { + // A helper for debugging scopes without printing parent scopes + fn debug_truncated(&'a self) -> impl fmt::Debug + 'a { + fmt::from_fn(move |f| match self { + Self::Binder { bound_vars, scope_type, hir_id, where_bound_origin, s: _ } => f + .debug_struct("Binder") + .field("bound_vars", bound_vars) + .field("scope_type", scope_type) + .field("hir_id", hir_id) + .field("where_bound_origin", where_bound_origin) + .field("s", &"..") + .finish(), + Self::Opaque { captures, def_id, s: _ } => f + .debug_struct("Opaque") + .field("def_id", def_id) + .field("captures", &captures.borrow()) + .field("s", &"..") + .finish(), + Self::Body { id, s: _ } => { + f.debug_struct("Body").field("id", id).field("s", &"..").finish() + } + Self::ObjectLifetimeDefault { lifetime, s: _ } => f + .debug_struct("ObjectLifetimeDefault") + .field("lifetime", lifetime) + .field("s", &"..") + .finish(), + Self::Supertrait { bound_vars, s: _ } => f + .debug_struct("Supertrait") + .field("bound_vars", bound_vars) + .field("s", &"..") + .finish(), + Self::TraitRefBoundary { s: _ } => f.debug_struct("TraitRefBoundary").finish(), + Self::LateBoundary { s: _, what, deny_late_regions } => f + .debug_struct("LateBoundary") + .field("what", what) + .field("deny_late_regions", deny_late_regions) + .finish(), + Self::Root { opt_parent_item } => { + f.debug_struct("Root").field("opt_parent_item", &opt_parent_item).finish() + } + }) + } +} + #[derive(Copy, Clone, Debug)] enum BinderScopeType { /// Any non-concatenating binder scopes. @@ -200,52 +244,6 @@ enum BinderScopeType { Concatenating, } -// A helper struct for debugging scopes without printing parent scopes -struct TruncatedScopeDebug<'a>(&'a Scope<'a>); - -impl<'a> fmt::Debug for TruncatedScopeDebug<'a> { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - match self.0 { - Scope::Binder { bound_vars, scope_type, hir_id, where_bound_origin, s: _ } => f - .debug_struct("Binder") - .field("bound_vars", bound_vars) - .field("scope_type", scope_type) - .field("hir_id", hir_id) - .field("where_bound_origin", where_bound_origin) - .field("s", &"..") - .finish(), - Scope::Opaque { captures, def_id, s: _ } => f - .debug_struct("Opaque") - .field("def_id", def_id) - .field("captures", &captures.borrow()) - .field("s", &"..") - .finish(), - Scope::Body { id, s: _ } => { - f.debug_struct("Body").field("id", id).field("s", &"..").finish() - } - Scope::ObjectLifetimeDefault { lifetime, s: _ } => f - .debug_struct("ObjectLifetimeDefault") - .field("lifetime", lifetime) - .field("s", &"..") - .finish(), - Scope::Supertrait { bound_vars, s: _ } => f - .debug_struct("Supertrait") - .field("bound_vars", bound_vars) - .field("s", &"..") - .finish(), - Scope::TraitRefBoundary { s: _ } => f.debug_struct("TraitRefBoundary").finish(), - Scope::LateBoundary { s: _, what, deny_late_regions } => f - .debug_struct("LateBoundary") - .field("what", what) - .field("deny_late_regions", deny_late_regions) - .finish(), - Scope::Root { opt_parent_item } => { - f.debug_struct("Root").field("opt_parent_item", &opt_parent_item).finish() - } - } - } -} - type ScopeRef<'a> = &'a Scope<'a>; pub(crate) fn provide(providers: &mut Providers) { @@ -1144,7 +1142,7 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> { { let BoundVarContext { tcx, map, .. } = self; let mut this = BoundVarContext { tcx: *tcx, map, scope: &wrap_scope }; - let span = debug_span!("scope", scope = ?TruncatedScopeDebug(this.scope)); + let span = debug_span!("scope", scope = ?this.scope.debug_truncated()); { let _enter = span.enter(); f(&mut this); diff --git a/compiler/rustc_hir_analysis/src/lib.rs b/compiler/rustc_hir_analysis/src/lib.rs index a42a168234f0..bc7d4365eeef 100644 --- a/compiler/rustc_hir_analysis/src/lib.rs +++ b/compiler/rustc_hir_analysis/src/lib.rs @@ -63,6 +63,7 @@ This API is completely unstable and subject to change. #![doc(rust_logo)] #![feature(assert_matches)] #![feature(coroutines)] +#![feature(debug_closure_helpers)] #![feature(if_let_guard)] #![feature(iter_from_coroutine)] #![feature(iter_intersperse)] diff --git a/compiler/rustc_middle/src/lib.rs b/compiler/rustc_middle/src/lib.rs index 04a06ba7464c..bbe23d8abe8a 100644 --- a/compiler/rustc_middle/src/lib.rs +++ b/compiler/rustc_middle/src/lib.rs @@ -40,6 +40,7 @@ #![feature(const_type_name)] #![feature(core_intrinsics)] #![feature(coroutines)] +#![feature(debug_closure_helpers)] #![feature(decl_macro)] #![feature(discriminant_kind)] #![feature(extern_types)] diff --git a/compiler/rustc_middle/src/mir/query.rs b/compiler/rustc_middle/src/mir/query.rs index db5da941f1e7..50494355e3e4 100644 --- a/compiler/rustc_middle/src/mir/query.rs +++ b/compiler/rustc_middle/src/mir/query.rs @@ -1,6 +1,5 @@ //! Values computed by queries that use MIR. -use std::cell::Cell; use std::fmt::{self, Debug}; use rustc_abi::{FieldIdx, VariantIdx}; @@ -62,55 +61,26 @@ pub struct CoroutineLayout<'tcx> { impl Debug for CoroutineLayout<'_> { fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { - /// Prints an iterator of (key, value) tuples as a map. - struct MapPrinter<'a, K, V>(Cell + 'a>>>); - impl<'a, K, V> MapPrinter<'a, K, V> { - fn new(iter: impl Iterator + 'a) -> Self { - Self(Cell::new(Some(Box::new(iter)))) - } - } - impl<'a, K: Debug, V: Debug> Debug for MapPrinter<'a, K, V> { - fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { - fmt.debug_map().entries(self.0.take().unwrap()).finish() - } - } - - /// Prints the coroutine variant name. - struct GenVariantPrinter(VariantIdx); - impl From for GenVariantPrinter { - fn from(idx: VariantIdx) -> Self { - GenVariantPrinter(idx) - } - } - impl Debug for GenVariantPrinter { - fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { - let variant_name = ty::CoroutineArgs::variant_name(self.0); - if fmt.alternate() { - write!(fmt, "{:9}({:?})", variant_name, self.0) - } else { - write!(fmt, "{variant_name}") - } - } - } - - /// Forces its contents to print in regular mode instead of alternate mode. - struct OneLinePrinter(T); - impl Debug for OneLinePrinter { - fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { - write!(fmt, "{:?}", self.0) - } - } - fmt.debug_struct("CoroutineLayout") - .field("field_tys", &MapPrinter::new(self.field_tys.iter_enumerated())) - .field( - "variant_fields", - &MapPrinter::new( - self.variant_fields - .iter_enumerated() - .map(|(k, v)| (GenVariantPrinter(k), OneLinePrinter(v))), - ), - ) + .field_with("field_tys", |fmt| { + fmt.debug_map().entries(self.field_tys.iter_enumerated()).finish() + }) + .field_with("variant_fields", |fmt| { + let mut map = fmt.debug_map(); + for (idx, fields) in self.variant_fields.iter_enumerated() { + map.key_with(|fmt| { + let variant_name = ty::CoroutineArgs::variant_name(idx); + if fmt.alternate() { + write!(fmt, "{variant_name:9}({idx:?})") + } else { + write!(fmt, "{variant_name}") + } + }); + // Force variant fields to print in regular mode instead of alternate mode. + map.value_with(|fmt| write!(fmt, "{fields:?}")); + } + map.finish() + }) .field("storage_conflicts", &self.storage_conflicts) .finish() } diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index aeb734ba3f65..d1079743004b 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -2325,51 +2325,41 @@ macro_rules! sty_debug_print { } impl<'tcx> TyCtxt<'tcx> { - pub fn debug_stats(self) -> impl std::fmt::Debug + 'tcx { - struct DebugStats<'tcx>(TyCtxt<'tcx>); + pub fn debug_stats(self) -> impl fmt::Debug + 'tcx { + fmt::from_fn(move |fmt| { + sty_debug_print!( + fmt, + self, + Adt, + Array, + Slice, + RawPtr, + Ref, + FnDef, + FnPtr, + UnsafeBinder, + Placeholder, + Coroutine, + CoroutineWitness, + Dynamic, + Closure, + CoroutineClosure, + Tuple, + Bound, + Param, + Infer, + Alias, + Pat, + Foreign + )?; - impl<'tcx> std::fmt::Debug for DebugStats<'tcx> { - fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - sty_debug_print!( - fmt, - self.0, - Adt, - Array, - Slice, - RawPtr, - Ref, - FnDef, - FnPtr, - UnsafeBinder, - Placeholder, - Coroutine, - CoroutineWitness, - Dynamic, - Closure, - CoroutineClosure, - Tuple, - Bound, - Param, - Infer, - Alias, - Pat, - Foreign - )?; + writeln!(fmt, "GenericArgs interner: #{}", self.interners.args.len())?; + writeln!(fmt, "Region interner: #{}", self.interners.region.len())?; + writeln!(fmt, "Const Allocation interner: #{}", self.interners.const_allocation.len())?; + writeln!(fmt, "Layout interner: #{}", self.interners.layout.len())?; - writeln!(fmt, "GenericArgs interner: #{}", self.0.interners.args.len())?; - writeln!(fmt, "Region interner: #{}", self.0.interners.region.len())?; - writeln!( - fmt, - "Const Allocation interner: #{}", - self.0.interners.const_allocation.len() - )?; - writeln!(fmt, "Layout interner: #{}", self.0.interners.layout.len())?; - - Ok(()) - } - } - - DebugStats(self) + Ok(()) + }) } } diff --git a/compiler/rustc_parse/src/parser/mod.rs b/compiler/rustc_parse/src/parser/mod.rs index 25d8eb9b4539..714a60cb179e 100644 --- a/compiler/rustc_parse/src/parser/mod.rs +++ b/compiler/rustc_parse/src/parser/mod.rs @@ -1598,45 +1598,35 @@ impl<'a> Parser<'a> { // Only used when debugging. #[allow(unused)] pub(crate) fn debug_lookahead(&self, lookahead: usize) -> impl fmt::Debug + '_ { - struct DebugParser<'dbg> { - parser: &'dbg Parser<'dbg>, - lookahead: usize, - } + fmt::from_fn(move |f| { + let mut dbg_fmt = f.debug_struct("Parser"); // or at least, one view of - impl fmt::Debug for DebugParser<'_> { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - let Self { parser, lookahead } = self; - let mut dbg_fmt = f.debug_struct("Parser"); // or at least, one view of - - // we don't need N spans, but we want at least one, so print all of prev_token - dbg_fmt.field("prev_token", &parser.prev_token); - let mut tokens = vec![]; - for i in 0..*lookahead { - let tok = parser.look_ahead(i, |tok| tok.kind.clone()); - let is_eof = tok == TokenKind::Eof; - tokens.push(tok); - if is_eof { - // Don't look ahead past EOF. - break; - } + // we don't need N spans, but we want at least one, so print all of prev_token + dbg_fmt.field("prev_token", &self.prev_token); + let mut tokens = vec![]; + for i in 0..lookahead { + let tok = self.look_ahead(i, |tok| tok.kind.clone()); + let is_eof = tok == TokenKind::Eof; + tokens.push(tok); + if is_eof { + // Don't look ahead past EOF. + break; } - dbg_fmt.field_with("tokens", |field| field.debug_list().entries(tokens).finish()); - dbg_fmt.field("approx_token_stream_pos", &parser.num_bump_calls); - - // some fields are interesting for certain values, as they relate to macro parsing - if let Some(subparser) = parser.subparser_name { - dbg_fmt.field("subparser_name", &subparser); - } - if let Recovery::Forbidden = parser.recovery { - dbg_fmt.field("recovery", &parser.recovery); - } - - // imply there's "more to know" than this view - dbg_fmt.finish_non_exhaustive() } - } + dbg_fmt.field_with("tokens", |field| field.debug_list().entries(tokens).finish()); + dbg_fmt.field("approx_token_stream_pos", &self.num_bump_calls); - DebugParser { parser: self, lookahead } + // some fields are interesting for certain values, as they relate to macro parsing + if let Some(subparser) = self.subparser_name { + dbg_fmt.field("subparser_name", &subparser); + } + if let Recovery::Forbidden = self.recovery { + dbg_fmt.field("recovery", &self.recovery); + } + + // imply there's "more to know" than this view + dbg_fmt.finish_non_exhaustive() + }) } pub fn clear_expected_token_types(&mut self) { From f24b0d358ac32af14994657865e1b4493550dc7a Mon Sep 17 00:00:00 2001 From: Antoni Boucher Date: Fri, 24 Jan 2025 10:48:53 -0500 Subject: [PATCH 31/81] Add comment to explain why CG_RUSTFLAGS is needed --- build_system/src/build.rs | 2 ++ build_system/src/config.rs | 2 ++ 2 files changed, 4 insertions(+) diff --git a/build_system/src/build.rs b/build_system/src/build.rs index d0ced211a616..a027c82a0b56 100644 --- a/build_system/src/build.rs +++ b/build_system/src/build.rs @@ -150,6 +150,8 @@ pub fn build_sysroot(env: &HashMap, config: &ConfigInfo) -> Resu "debug" }; + // We have a different environment variable than RUSTFLAGS to make sure those flags are only + // sent to rustc_codegen_gcc and not the LLVM backend. if let Ok(cg_rustflags) = std::env::var("CG_RUSTFLAGS") { rustflags.push(' '); rustflags.push_str(&cg_rustflags); diff --git a/build_system/src/config.rs b/build_system/src/config.rs index 37b4b68950e4..f10eee2651a7 100644 --- a/build_system/src/config.rs +++ b/build_system/src/config.rs @@ -381,6 +381,8 @@ impl ConfigInfo { } // This environment variable is useful in case we want to change options of rustc commands. + // We have a different environment variable than RUSTFLAGS to make sure those flags are + // only sent to rustc_codegen_gcc and not the LLVM backend. if let Some(cg_rustflags) = env.get("CG_RUSTFLAGS") { rustflags.extend_from_slice(&split_args(&cg_rustflags)?); } From 4798615ad4199a87f5ad880ad757b67b6db6e4f8 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Fri, 24 Jan 2025 16:09:26 +0100 Subject: [PATCH 32/81] Add `--gcc-path` option --- build_system/src/build.rs | 8 ++++++-- build_system/src/config.rs | 40 ++++++++++++++++++++++++++------------ build_system/src/info.rs | 4 +++- build_system/src/test.rs | 7 +++++-- 4 files changed, 42 insertions(+), 17 deletions(-) diff --git a/build_system/src/build.rs b/build_system/src/build.rs index d0ced211a616..2f48d78e6a8b 100644 --- a/build_system/src/build.rs +++ b/build_system/src/build.rs @@ -184,8 +184,12 @@ pub fn build_sysroot(env: &HashMap, config: &ConfigInfo) -> Resu fn build_codegen(args: &mut BuildArg) -> Result<(), String> { let mut env = HashMap::new(); - env.insert("LD_LIBRARY_PATH".to_string(), args.config_info.gcc_path.clone()); - env.insert("LIBRARY_PATH".to_string(), args.config_info.gcc_path.clone()); + let gcc_path = + args.config_info.gcc_path.clone().expect( + "The config module should have emitted an error if the GCC path wasn't provided", + ); + env.insert("LD_LIBRARY_PATH".to_string(), gcc_path.clone()); + env.insert("LIBRARY_PATH".to_string(), gcc_path); if args.config_info.no_default_features { env.insert("RUSTFLAGS".to_string(), "-Csymbol-mangling-version=v0".to_string()); diff --git a/build_system/src/config.rs b/build_system/src/config.rs index 37b4b68950e4..e8eeb559c79d 100644 --- a/build_system/src/config.rs +++ b/build_system/src/config.rs @@ -112,7 +112,7 @@ pub struct ConfigInfo { pub sysroot_panic_abort: bool, pub cg_backend_path: String, pub sysroot_path: String, - pub gcc_path: String, + pub gcc_path: Option, config_file: Option, // This is used in particular in rust compiler bootstrap because it doesn't run at the root // of the `cg_gcc` folder, making it complicated for us to get access to local files we need @@ -173,6 +173,14 @@ impl ConfigInfo { "--release-sysroot" => self.sysroot_release_channel = true, "--release" => self.channel = Channel::Release, "--sysroot-panic-abort" => self.sysroot_panic_abort = true, + "--gcc-path" => match args.next() { + Some(arg) if !arg.is_empty() => { + self.gcc_path = Some(arg.into()); + } + _ => { + return Err("Expected a value after `--gcc-path`, found nothing".to_string()); + } + }, "--cg_gcc-path" => match args.next() { Some(arg) if !arg.is_empty() => { self.cg_gcc_path = Some(arg.into()); @@ -260,8 +268,9 @@ impl ConfigInfo { create_symlink(&libgccjit_so, output_dir.join(&format!("{}.0", libgccjit_so_name)))?; } - self.gcc_path = output_dir.display().to_string(); - println!("Using `{}` as path for libgccjit", self.gcc_path); + let gcc_path = output_dir.display().to_string(); + println!("Using `{}` as path for libgccjit", gcc_path); + self.gcc_path = Some(gcc_path); Ok(()) } @@ -273,6 +282,11 @@ impl ConfigInfo { } pub fn setup_gcc_path(&mut self) -> Result<(), String> { + // If the user used the `--gcc-path` option, no need to look at `config.toml` content + // since we already have everything we need. + if self.gcc_path.is_some() { + return Ok(()); + } let config_file = match self.config_file.as_deref() { Some(config_file) => config_file.into(), None => self.compute_path("config.toml"), @@ -283,12 +297,10 @@ impl ConfigInfo { self.download_gccjit_if_needed()?; return Ok(()); } - self.gcc_path = match gcc_path { - Some(path) => path, - None => { - return Err(format!("missing `gcc-path` value from `{}`", config_file.display(),)); - } - }; + if gcc_path.is_none() { + return Err(format!("missing `gcc-path` value from `{}`", config_file.display())); + } + self.gcc_path = gcc_path; Ok(()) } @@ -299,10 +311,13 @@ impl ConfigInfo { ) -> Result<(), String> { env.insert("CARGO_INCREMENTAL".to_string(), "0".to_string()); - if self.gcc_path.is_empty() && !use_system_gcc { + if self.gcc_path.is_none() && !use_system_gcc { self.setup_gcc_path()?; } - env.insert("GCC_PATH".to_string(), self.gcc_path.clone()); + let gcc_path = self.gcc_path.clone().expect( + "The config module should have emitted an error if the GCC path wasn't provided", + ); + env.insert("GCC_PATH".to_string(), gcc_path.clone()); if self.cargo_target_dir.is_empty() { match env.get("CARGO_TARGET_DIR").filter(|dir| !dir.is_empty()) { @@ -414,7 +429,7 @@ impl ConfigInfo { "{target}:{sysroot}:{gcc_path}", target = self.cargo_target_dir, sysroot = sysroot.display(), - gcc_path = self.gcc_path, + gcc_path = gcc_path, ); env.insert("LIBRARY_PATH".to_string(), ld_library_path.clone()); env.insert("LD_LIBRARY_PATH".to_string(), ld_library_path.clone()); @@ -459,6 +474,7 @@ impl ConfigInfo { --release-sysroot : Build sysroot in release mode --sysroot-panic-abort : Build the sysroot without unwinding support --config-file : Location of the config file to be used + --gcc-path : Location of the GCC root folder --cg_gcc-path : Location of the rustc_codegen_gcc root folder (used when ran from another directory) --no-default-features : Add `--no-default-features` flag to cargo commands diff --git a/build_system/src/info.rs b/build_system/src/info.rs index ea38791d38c9..bd891de2eb4c 100644 --- a/build_system/src/info.rs +++ b/build_system/src/info.rs @@ -14,6 +14,8 @@ pub fn run() -> Result<(), String> { } config.no_download = true; config.setup_gcc_path()?; - println!("{}", config.gcc_path); + if let Some(gcc_path) = config.gcc_path { + println!("{}", gcc_path); + } Ok(()) } diff --git a/build_system/src/test.rs b/build_system/src/test.rs index 7cc7336612c7..efd7b2b8df3a 100644 --- a/build_system/src/test.rs +++ b/build_system/src/test.rs @@ -1255,8 +1255,11 @@ pub fn run() -> Result<(), String> { if !args.use_system_gcc { args.config_info.setup_gcc_path()?; - env.insert("LIBRARY_PATH".to_string(), args.config_info.gcc_path.clone()); - env.insert("LD_LIBRARY_PATH".to_string(), args.config_info.gcc_path.clone()); + let gcc_path = args.config_info.gcc_path.clone().expect( + "The config module should have emitted an error if the GCC path wasn't provided", + ); + env.insert("LIBRARY_PATH".to_string(), gcc_path.clone()); + env.insert("LD_LIBRARY_PATH".to_string(), gcc_path); } build_if_no_backend(&env, &args)?; From b8218f0d2bcca50dc0128393015207aa649587c0 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Fri, 24 Jan 2025 16:40:47 +0100 Subject: [PATCH 33/81] Add log to mention what GCC path the build script is using and where it comes from --- build_system/src/config.rs | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/build_system/src/config.rs b/build_system/src/config.rs index e8eeb559c79d..843f87c8be6b 100644 --- a/build_system/src/config.rs +++ b/build_system/src/config.rs @@ -284,7 +284,11 @@ impl ConfigInfo { pub fn setup_gcc_path(&mut self) -> Result<(), String> { // If the user used the `--gcc-path` option, no need to look at `config.toml` content // since we already have everything we need. - if self.gcc_path.is_some() { + if let Some(gcc_path) = &self.gcc_path { + println!( + "`--gcc-path` was provided, ignoring config file. Using `{}` as path for libgccjit", + gcc_path + ); return Ok(()); } let config_file = match self.config_file.as_deref() { @@ -297,10 +301,15 @@ impl ConfigInfo { self.download_gccjit_if_needed()?; return Ok(()); } - if gcc_path.is_none() { + let Some(gcc_path) = gcc_path else { return Err(format!("missing `gcc-path` value from `{}`", config_file.display())); - } - self.gcc_path = gcc_path; + }; + println!( + "GCC path retrieved from `{}`. Using `{}` as path for libgccjit", + config_file.display(), + gcc_path + ); + self.gcc_path = Some(gcc_path); Ok(()) } From 2d11559f56bbe112b13d2fe43fbfd40b7258f34e Mon Sep 17 00:00:00 2001 From: Scott McMurray Date: Fri, 24 Jan 2025 09:51:59 -0800 Subject: [PATCH 34/81] Add an `unchecked_div` alias to the `Div>` impls --- library/core/src/num/nonzero.rs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/library/core/src/num/nonzero.rs b/library/core/src/num/nonzero.rs index dbce64420ac4..51f407096cf4 100644 --- a/library/core/src/num/nonzero.rs +++ b/library/core/src/num/nonzero.rs @@ -1165,8 +1165,12 @@ macro_rules! nonzero_integer_signedness_dependent_impls { impl Div> for $Int { type Output = $Int; + /// Same as `self / other.get()`, but because `other` is a `NonZero<_>`, + /// there's never a runtime check for division-by-zero. + /// /// This operation rounds towards zero, truncating any fractional /// part of the exact result, and cannot panic. + #[doc(alias = "unchecked_div")] #[inline] fn div(self, other: NonZero<$Int>) -> $Int { // SAFETY: Division by zero is checked because `other` is non-zero, @@ -1177,6 +1181,9 @@ macro_rules! nonzero_integer_signedness_dependent_impls { #[stable(feature = "nonzero_div_assign", since = "1.79.0")] impl DivAssign> for $Int { + /// Same as `self /= other.get()`, but because `other` is a `NonZero<_>`, + /// there's never a runtime check for division-by-zero. + /// /// This operation rounds towards zero, truncating any fractional /// part of the exact result, and cannot panic. #[inline] From 2444adf27c3c4e638c121b685bc3d4d57bb9d51f Mon Sep 17 00:00:00 2001 From: Ed Page Date: Fri, 13 Dec 2024 14:49:40 -0600 Subject: [PATCH 35/81] fix(libtest): Deprecate '--logfile' rust-lang/testing-devex-team#9 proposed changing the behavior of `--logfile`. The given reasons were: (1) Bazel can't programmatically process stdout. This seems like a limitation in Bazel and we recommend focusing on that. If we look at the wider Rust ecosystem, Rustc and Cargo don't support any such mechanism and the Cargo team rejected having one. Expecting this in libtest when its not supported elsewhere seems too specialized. (2) Tests that leak out non-programmatic output that intermixes with programmatic output. We acknowledge this is a problem to be evaluated but we need to make sure we are stepping back and gathering requirements, rather than assuming `--logfile` will fit the needs. Independent of the motive, regarding using or changing `--logfile` (1) Most ways to do it would be a breaking change, like if we respect any stable `--format`. As suggested above, we could specialize this to new `--format` values but that would be confusing for some values to apply but not others. (2) Other ways of solving this add new features to lib`test` when we are instead wanting to limit the feature set it has to minimize the compatibility surface that has to be maintained and the burden it would put on third party harnesses which are a focus area. Examples include `--format compact` or a `--log-format` flag (3) The existence of `--logfile` dates back quite a ways (https://github.com/rust-lang/rust/commit/5cc050b265509c19717e11e12dd785d8c73f5b11, rust-lang/rust#2127) and the history gives the impression this more of slipped through rather than being an intended feature (see also https://github.com/rust-lang/rust/pull/82350#discussion_r579732071). Deprecation would better match to how it has been treated. By deprecating this, we do not expect custom test harnesses (rust-lang/testing-devex-team#2) to implement this. T-testing-devex held an FCP for deprecating in rust-lang/testing-devex-team#9 though according to [RFC #3455](https://rust-lang.github.io/rfcs/3455-t-test.html), this is still subject to final approval from T-libs-api. --- library/test/src/cli.rs | 8 ++++++-- src/doc/rustc/src/tests/index.md | 2 ++ 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/library/test/src/cli.rs b/library/test/src/cli.rs index 52c809176234..ef6786f43167 100644 --- a/library/test/src/cli.rs +++ b/library/test/src/cli.rs @@ -1,7 +1,7 @@ //! Module converting command-line arguments into test configuration. use std::env; -use std::io::{self, IsTerminal}; +use std::io::{self, IsTerminal, Write}; use std::path::PathBuf; use super::options::{ColorConfig, Options, OutputFormat, RunIgnored}; @@ -58,7 +58,7 @@ fn optgroups() -> getopts::Options { .optflag("", "bench", "Run benchmarks instead of tests") .optflag("", "list", "List all tests and benchmarks") .optflag("h", "help", "Display this message") - .optopt("", "logfile", "Write logs to the specified file", "PATH") + .optopt("", "logfile", "Write logs to the specified file (deprecated)", "PATH") .optflag( "", "nocapture", @@ -281,6 +281,10 @@ fn parse_opts_impl(matches: getopts::Matches) -> OptRes { let options = Options::new().display_output(matches.opt_present("show-output")); + if logfile.is_some() { + let _ = write!(io::stderr(), "warning: `--logfile` is deprecated"); + } + let test_opts = TestOpts { list, filters, diff --git a/src/doc/rustc/src/tests/index.md b/src/doc/rustc/src/tests/index.md index 32baed9c9449..d2026513d2f0 100644 --- a/src/doc/rustc/src/tests/index.md +++ b/src/doc/rustc/src/tests/index.md @@ -268,6 +268,8 @@ Controls the format of the output. Valid options: Writes the results of the tests to the given file. +This option is deprecated. + #### `--report-time` ⚠️ 🚧 This option is [unstable](#unstable-options), and requires the `-Z From 12e73aec910ba8ad6fc673cacf7d5138523c8d30 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Fri, 24 Jan 2025 22:42:42 +0100 Subject: [PATCH 36/81] Fix `--use-system-gcc` option handling --- build_system/src/config.rs | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/build_system/src/config.rs b/build_system/src/config.rs index 0904ea871cd4..4f9fcc971514 100644 --- a/build_system/src/config.rs +++ b/build_system/src/config.rs @@ -320,12 +320,16 @@ impl ConfigInfo { ) -> Result<(), String> { env.insert("CARGO_INCREMENTAL".to_string(), "0".to_string()); - if self.gcc_path.is_none() && !use_system_gcc { - self.setup_gcc_path()?; - } - let gcc_path = self.gcc_path.clone().expect( - "The config module should have emitted an error if the GCC path wasn't provided", - ); + let gcc_path = if !use_system_gcc { + if self.gcc_path.is_none() { + self.setup_gcc_path()?; + } + self.gcc_path.clone().expect( + "The config module should have emitted an error if the GCC path wasn't provided", + ) + } else { + String::new() + }; env.insert("GCC_PATH".to_string(), gcc_path.clone()); if self.cargo_target_dir.is_empty() { From 8eebbbaac2adabf4e442eadccf71e6f470871b37 Mon Sep 17 00:00:00 2001 From: Josh Stone Date: Thu, 23 Jan 2025 12:28:52 -0800 Subject: [PATCH 37/81] ci.py: check the return code in `run-local` If the run fails, it should report that and return a non-zero exit status. The simplest way to do that is with `run(..., check=True)`, which raises a `CalledProcessError`. --- src/ci/github-actions/ci.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ci/github-actions/ci.py b/src/ci/github-actions/ci.py index b7dac412dbec..c93766ef33a0 100755 --- a/src/ci/github-actions/ci.py +++ b/src/ci/github-actions/ci.py @@ -249,7 +249,7 @@ def run_workflow_locally(job_data: Dict[str, Any], job_name: str, pr_jobs: bool) env = os.environ.copy() env.update(custom_env) - subprocess.run(args, env=env) + subprocess.run(args, env=env, check=True) def calculate_job_matrix(job_data: Dict[str, Any]): From 1dfc437aaf09185c9830b6b5214bc2a089fd297f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Fri, 24 Jan 2025 23:34:34 +0000 Subject: [PATCH 38/81] Account for mutable borrow in argument suggestion ``` error: value assigned to `object` is never read --> $DIR/mut-arg-of-borrowed-type-meant-to-be-arg-of-mut-borrow.rs:21:5 | LL | object = &mut object2; | ^^^^^^ | help: you might have meant to mutate the pointed at value being passed in, instead of changing the reference in the local binding | LL ~ fn change_object3(object: &mut Object) { LL | LL | let object2 = Object; LL ~ *object = object2; | ``` instead of ``` error: value assigned to `object` is never read --> $DIR/mut-arg-of-borrowed-type-meant-to-be-arg-of-mut-borrow.rs:21:5 | LL | object = &mut object2; | ^^^^^^ | help: you might have meant to mutate the pointed at value being passed in, instead of changing the reference in the local binding | LL ~ fn change_object3(object: &mut mut Object) { LL | LL | let object2 = Object; LL ~ *object = object2; | ``` Fix #136028. --- compiler/rustc_hir_typeck/src/demand.rs | 38 ++++----- compiler/rustc_passes/src/errors.rs | 2 +- compiler/rustc_passes/src/liveness.rs | 16 ++-- ...d-type-meant-to-be-arg-of-mut-borrow.fixed | 18 ++++- ...owed-type-meant-to-be-arg-of-mut-borrow.rs | 20 +++-- ...-type-meant-to-be-arg-of-mut-borrow.stderr | 77 +++++++++++++------ 6 files changed, 114 insertions(+), 57 deletions(-) diff --git a/compiler/rustc_hir_typeck/src/demand.rs b/compiler/rustc_hir_typeck/src/demand.rs index 367e7c6de953..bc0766705854 100644 --- a/compiler/rustc_hir_typeck/src/demand.rs +++ b/compiler/rustc_hir_typeck/src/demand.rs @@ -851,32 +851,32 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { && let hir::PatKind::Binding(hir::BindingMode::MUT, _hir_id, ident, _) = pat.kind // Look for the type corresponding to the argument pattern we have in the argument list. - && let Some(ty_sugg) = fn_decl + && let Some(ty_ref) = fn_decl .inputs .iter() - .filter_map(|ty| { - if ty.span == *ty_span - && let hir::TyKind::Ref(lt, x) = ty.kind - { - // `&'name Ty` -> `&'name mut Ty` or `&Ty` -> `&mut Ty` - Some(( - x.ty.span.shrink_to_lo(), - format!( - "{}mut ", - if lt.ident.span.lo() == lt.ident.span.hi() { "" } else { " " } - ), - )) - } else { - None - } + .filter_map(|ty| match ty.kind { + hir::TyKind::Ref(lt, mut_ty) if ty.span == *ty_span => Some((lt, mut_ty)), + _ => None, }) .next() { - let sugg = vec![ - ty_sugg, + let mut sugg = if ty_ref.1.mutbl.is_mut() { + // Leave `&'name mut Ty` and `&mut Ty` as they are (#136028). + vec![] + } else { + // `&'name Ty` -> `&'name mut Ty` or `&Ty` -> `&mut Ty` + vec![( + ty_ref.1.ty.span.shrink_to_lo(), + format!( + "{}mut ", + if ty_ref.0.ident.span.lo() == ty_ref.0.ident.span.hi() { "" } else { " " }, + ), + )] + }; + sugg.extend([ (pat.span.until(ident.span), String::new()), (lhs.span.shrink_to_lo(), "*".to_string()), - ]; + ]); // We suggest changing the argument from `mut ident: &Ty` to `ident: &'_ mut Ty` and the // assignment from `ident = val;` to `*ident = val;`. err.multipart_suggestion_verbose( diff --git a/compiler/rustc_passes/src/errors.rs b/compiler/rustc_passes/src/errors.rs index 3d38b00e99f2..0e05e1c867b4 100644 --- a/compiler/rustc_passes/src/errors.rs +++ b/compiler/rustc_passes/src/errors.rs @@ -1789,7 +1789,7 @@ pub(crate) struct UnusedAssign { pub(crate) struct UnusedAssignSuggestion { pub pre: &'static str, #[suggestion_part(code = "{pre}mut ")] - pub ty_span: Span, + pub ty_span: Option, #[suggestion_part(code = "")] pub ty_ref_span: Span, #[suggestion_part(code = "*")] diff --git a/compiler/rustc_passes/src/liveness.rs b/compiler/rustc_passes/src/liveness.rs index 426899a4d5c6..73da8855e10c 100644 --- a/compiler/rustc_passes/src/liveness.rs +++ b/compiler/rustc_passes/src/liveness.rs @@ -1620,24 +1620,28 @@ impl<'tcx> Liveness<'_, 'tcx> { && let item = self.ir.tcx.hir_owner_node(item_id) && let Some(fn_decl) = item.fn_decl() && let hir::PatKind::Binding(hir::BindingMode::MUT, _hir_id, ident, _) = pat.kind - && let Some((ty_span, pre)) = fn_decl + && let Some((lt, mut_ty)) = fn_decl .inputs .iter() .filter_map(|ty| { if ty.span == *ty_span && let hir::TyKind::Ref(lt, mut_ty) = ty.kind { - // `&'name Ty` -> `&'name mut Ty` or `&Ty` -> `&mut Ty` - Some(( - mut_ty.ty.span.shrink_to_lo(), - if lt.ident.span.lo() == lt.ident.span.hi() { "" } else { " " }, - )) + Some((lt, mut_ty)) } else { None } }) .next() { + let ty_span = if mut_ty.mutbl.is_mut() { + // Leave `&'name mut Ty` and `&mut Ty` as they are (#136028). + None + } else { + // `&'name Ty` -> `&'name mut Ty` or `&Ty` -> `&mut Ty` + Some(mut_ty.ty.span.shrink_to_lo()) + }; + let pre = if lt.ident.span.lo() == lt.ident.span.hi() { "" } else { " " }; Some(errors::UnusedAssignSuggestion { ty_span, pre, diff --git a/tests/ui/fn/mut-arg-of-borrowed-type-meant-to-be-arg-of-mut-borrow.fixed b/tests/ui/fn/mut-arg-of-borrowed-type-meant-to-be-arg-of-mut-borrow.fixed index 914ca1f3a065..b58c3a6720d0 100644 --- a/tests/ui/fn/mut-arg-of-borrowed-type-meant-to-be-arg-of-mut-borrow.fixed +++ b/tests/ui/fn/mut-arg-of-borrowed-type-meant-to-be-arg-of-mut-borrow.fixed @@ -1,17 +1,26 @@ //@ run-rustfix #![deny(unused_assignments, unused_variables)] +#![allow(unused_mut)] struct Object; fn change_object(object: &mut Object) { //~ HELP you might have meant to mutate - let object2 = Object; - *object = object2; //~ ERROR mismatched types + let object2 = Object; + *object = object2; //~ ERROR mismatched types } fn change_object2(object: &mut Object) { //~ ERROR variable `object` is assigned to, but never used + //~^ HELP you might have meant to mutate + let object2 = Object; + *object = object2; + //~^ ERROR `object2` does not live long enough + //~| ERROR value assigned to `object` is never read +} + +fn change_object3(object: &mut Object) { //~ ERROR variable `object` is assigned to, but never used //~^ HELP you might have meant to mutate - let object2 = Object; + let mut object2 = Object; //~ HELP consider changing this to be mutable *object = object2; - //~^ ERROR `object2` does not live long enough + //~^ ERROR cannot borrow `object2` as mutable //~| ERROR value assigned to `object` is never read } @@ -19,4 +28,5 @@ fn main() { let mut object = Object; change_object(&mut object); change_object2(&mut object); + change_object3(&mut object); } diff --git a/tests/ui/fn/mut-arg-of-borrowed-type-meant-to-be-arg-of-mut-borrow.rs b/tests/ui/fn/mut-arg-of-borrowed-type-meant-to-be-arg-of-mut-borrow.rs index 331359a98d14..1fd222e0db17 100644 --- a/tests/ui/fn/mut-arg-of-borrowed-type-meant-to-be-arg-of-mut-borrow.rs +++ b/tests/ui/fn/mut-arg-of-borrowed-type-meant-to-be-arg-of-mut-borrow.rs @@ -1,17 +1,26 @@ //@ run-rustfix #![deny(unused_assignments, unused_variables)] +#![allow(unused_mut)] struct Object; fn change_object(mut object: &Object) { //~ HELP you might have meant to mutate - let object2 = Object; - object = object2; //~ ERROR mismatched types + let object2 = Object; + object = object2; //~ ERROR mismatched types } fn change_object2(mut object: &Object) { //~ ERROR variable `object` is assigned to, but never used + //~^ HELP you might have meant to mutate + let object2 = Object; + object = &object2; + //~^ ERROR `object2` does not live long enough + //~| ERROR value assigned to `object` is never read +} + +fn change_object3(mut object: &mut Object) { //~ ERROR variable `object` is assigned to, but never used //~^ HELP you might have meant to mutate - let object2 = Object; - object = &object2; - //~^ ERROR `object2` does not live long enough + let object2 = Object; //~ HELP consider changing this to be mutable + object = &mut object2; + //~^ ERROR cannot borrow `object2` as mutable //~| ERROR value assigned to `object` is never read } @@ -19,4 +28,5 @@ fn main() { let mut object = Object; change_object(&mut object); change_object2(&mut object); + change_object3(&mut object); } diff --git a/tests/ui/fn/mut-arg-of-borrowed-type-meant-to-be-arg-of-mut-borrow.stderr b/tests/ui/fn/mut-arg-of-borrowed-type-meant-to-be-arg-of-mut-borrow.stderr index e7e4003936a1..0330853d922f 100644 --- a/tests/ui/fn/mut-arg-of-borrowed-type-meant-to-be-arg-of-mut-borrow.stderr +++ b/tests/ui/fn/mut-arg-of-borrowed-type-meant-to-be-arg-of-mut-borrow.stderr @@ -1,24 +1,24 @@ error[E0308]: mismatched types - --> $DIR/mut-arg-of-borrowed-type-meant-to-be-arg-of-mut-borrow.rs:7:14 + --> $DIR/mut-arg-of-borrowed-type-meant-to-be-arg-of-mut-borrow.rs:8:13 | LL | fn change_object(mut object: &Object) { | ------- expected due to this parameter type -LL | let object2 = Object; -LL | object = object2; - | ^^^^^^^ expected `&Object`, found `Object` +LL | let object2 = Object; +LL | object = object2; + | ^^^^^^^ expected `&Object`, found `Object` | help: you might have meant to mutate the pointed at value being passed in, instead of changing the reference in the local binding | LL ~ fn change_object(object: &mut Object) { -LL | let object2 = Object; -LL ~ *object = object2; +LL | let object2 = Object; +LL ~ *object = object2; | error: value assigned to `object` is never read - --> $DIR/mut-arg-of-borrowed-type-meant-to-be-arg-of-mut-borrow.rs:13:5 + --> $DIR/mut-arg-of-borrowed-type-meant-to-be-arg-of-mut-borrow.rs:14:4 | -LL | object = &object2; - | ^^^^^^ +LL | object = &object2; + | ^^^^^^ | note: the lint level is defined here --> $DIR/mut-arg-of-borrowed-type-meant-to-be-arg-of-mut-borrow.rs:2:9 @@ -29,12 +29,12 @@ help: you might have meant to mutate the pointed at value being passed in, inste | LL ~ fn change_object2(object: &mut Object) { LL | -LL | let object2 = Object; -LL ~ *object = object2; +LL | let object2 = Object; +LL ~ *object = object2; | error: variable `object` is assigned to, but never used - --> $DIR/mut-arg-of-borrowed-type-meant-to-be-arg-of-mut-borrow.rs:10:23 + --> $DIR/mut-arg-of-borrowed-type-meant-to-be-arg-of-mut-borrow.rs:11:23 | LL | fn change_object2(mut object: &Object) { | ^^^^^^ @@ -47,23 +47,56 @@ LL | #![deny(unused_assignments, unused_variables)] | ^^^^^^^^^^^^^^^^ error[E0597]: `object2` does not live long enough - --> $DIR/mut-arg-of-borrowed-type-meant-to-be-arg-of-mut-borrow.rs:13:14 + --> $DIR/mut-arg-of-borrowed-type-meant-to-be-arg-of-mut-borrow.rs:14:13 | LL | fn change_object2(mut object: &Object) { | - let's call the lifetime of this reference `'1` LL | -LL | let object2 = Object; - | ------- binding `object2` declared here -LL | object = &object2; - | ---------^^^^^^^^ - | | | - | | borrowed value does not live long enough - | assignment requires that `object2` is borrowed for `'1` +LL | let object2 = Object; + | ------- binding `object2` declared here +LL | object = &object2; + | ---------^^^^^^^^ + | | | + | | borrowed value does not live long enough + | assignment requires that `object2` is borrowed for `'1` ... LL | } | - `object2` dropped here while still borrowed -error: aborting due to 4 previous errors +error: value assigned to `object` is never read + --> $DIR/mut-arg-of-borrowed-type-meant-to-be-arg-of-mut-borrow.rs:22:5 + | +LL | object = &mut object2; + | ^^^^^^ + | +help: you might have meant to mutate the pointed at value being passed in, instead of changing the reference in the local binding + | +LL ~ fn change_object3(object: &mut Object) { +LL | +LL | let object2 = Object; +LL ~ *object = object2; + | -Some errors have detailed explanations: E0308, E0597. +error: variable `object` is assigned to, but never used + --> $DIR/mut-arg-of-borrowed-type-meant-to-be-arg-of-mut-borrow.rs:19:23 + | +LL | fn change_object3(mut object: &mut Object) { + | ^^^^^^ + | + = note: consider using `_object` instead + +error[E0596]: cannot borrow `object2` as mutable, as it is not declared as mutable + --> $DIR/mut-arg-of-borrowed-type-meant-to-be-arg-of-mut-borrow.rs:22:14 + | +LL | object = &mut object2; + | ^^^^^^^^^^^^ cannot borrow as mutable + | +help: consider changing this to be mutable + | +LL | let mut object2 = Object; + | +++ + +error: aborting due to 7 previous errors + +Some errors have detailed explanations: E0308, E0596, E0597. For more information about an error, try `rustc --explain E0308`. From 1d97a3e4d7f833675a8c5ae1120db915c99474d9 Mon Sep 17 00:00:00 2001 From: Kornel Date: Fri, 17 Jan 2025 12:31:40 +0100 Subject: [PATCH 39/81] Remove extra whitespace from rustdoc breadcrumbs for copypasting --- src/librustdoc/html/static/css/rustdoc.css | 9 +++------ src/librustdoc/html/templates/print_item.html | 4 ++-- 2 files changed, 5 insertions(+), 8 deletions(-) diff --git a/src/librustdoc/html/static/css/rustdoc.css b/src/librustdoc/html/static/css/rustdoc.css index a7b462936cc7..f487d66edac7 100644 --- a/src/librustdoc/html/static/css/rustdoc.css +++ b/src/librustdoc/html/static/css/rustdoc.css @@ -192,15 +192,12 @@ h1, h2, h3, h4 { .rustdoc-breadcrumbs { grid-area: main-heading-breadcrumbs; line-height: 1.25; - display: flex; - flex-wrap: wrap; - align-items: end; padding-top: 5px; + position: relative; + z-index: 1; } .rustdoc-breadcrumbs a { - padding: 4px 0; - margin: -4px 0; - z-index: 1; + padding: 5px 0 7px; } /* The only headings that get underlines are: Markdown-generated headings within the top-doc diff --git a/src/librustdoc/html/templates/print_item.html b/src/librustdoc/html/templates/print_item.html index 9fd575b2751e..62954dbb0232 100644 --- a/src/librustdoc/html/templates/print_item.html +++ b/src/librustdoc/html/templates/print_item.html @@ -1,13 +1,13 @@
{% if !path_components.is_empty() %} - +
{% for (i, component) in path_components.iter().enumerate() %} {% if i != 0 %} :: {% endif %} {{component.name}} {% endfor %} - +
{% endif %}

{{typ}} From 492d98564e42bf14f96996f1dea33c0228838e93 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9my=20Rakic?= Date: Fri, 24 Jan 2025 18:17:15 +0000 Subject: [PATCH 40/81] extract principal MIR dump function for cases where we want to dump the MIR to a given writer instead of a new file as the default does. this will be used when dumping the MIR to a buffer to process differently, e.g. post-process to escape for an HTML dump. --- compiler/rustc_middle/src/mir/pretty.rs | 63 ++++++++++++++++--------- 1 file changed, 42 insertions(+), 21 deletions(-) diff --git a/compiler/rustc_middle/src/mir/pretty.rs b/compiler/rustc_middle/src/mir/pretty.rs index ea35323ccc7f..3b4fba97e60b 100644 --- a/compiler/rustc_middle/src/mir/pretty.rs +++ b/compiler/rustc_middle/src/mir/pretty.rs @@ -1,8 +1,7 @@ use std::collections::BTreeSet; use std::fmt::{Display, Write as _}; -use std::fs; -use std::io::{self, Write as _}; use std::path::{Path, PathBuf}; +use std::{fs, io}; use rustc_abi::Size; use rustc_ast::InlineAsmTemplatePiece; @@ -149,37 +148,59 @@ pub fn dump_enabled(tcx: TyCtxt<'_>, pass_name: &str, def_id: DefId) -> bool { // `def_path_str()` would otherwise trigger `type_of`, and this can // run while we are already attempting to evaluate `type_of`. +/// Most use-cases of dumping MIR should use the [dump_mir] entrypoint instead, which will also +/// check if dumping MIR is enabled, and if this body matches the filters passed on the CLI. +/// +/// That being said, if the above requirements have been validated already, this function is where +/// most of the MIR dumping occurs, if one needs to export it to a file they have created with +/// [create_dump_file], rather than to a new file created as part of [dump_mir], or to stdout/stderr +/// for debugging purposes. +pub fn dump_mir_to_writer<'tcx, F>( + tcx: TyCtxt<'tcx>, + pass_name: &str, + disambiguator: &dyn Display, + body: &Body<'tcx>, + w: &mut dyn io::Write, + mut extra_data: F, + options: PrettyPrintMirOptions, +) -> io::Result<()> +where + F: FnMut(PassWhere, &mut dyn io::Write) -> io::Result<()>, +{ + // see notes on #41697 above + let def_path = + ty::print::with_forced_impl_filename_line!(tcx.def_path_str(body.source.def_id())); + // ignore-tidy-odd-backticks the literal below is fine + write!(w, "// MIR for `{def_path}")?; + match body.source.promoted { + None => write!(w, "`")?, + Some(promoted) => write!(w, "::{promoted:?}`")?, + } + writeln!(w, " {disambiguator} {pass_name}")?; + if let Some(ref layout) = body.coroutine_layout_raw() { + writeln!(w, "/* coroutine_layout = {layout:#?} */")?; + } + writeln!(w)?; + extra_data(PassWhere::BeforeCFG, w)?; + write_user_type_annotations(tcx, body, w)?; + write_mir_fn(tcx, body, &mut extra_data, w, options)?; + extra_data(PassWhere::AfterCFG, w) +} + fn dump_matched_mir_node<'tcx, F>( tcx: TyCtxt<'tcx>, pass_num: bool, pass_name: &str, disambiguator: &dyn Display, body: &Body<'tcx>, - mut extra_data: F, + extra_data: F, options: PrettyPrintMirOptions, ) where F: FnMut(PassWhere, &mut dyn io::Write) -> io::Result<()>, { let _: io::Result<()> = try { let mut file = create_dump_file(tcx, "mir", pass_num, pass_name, disambiguator, body)?; - // see notes on #41697 above - let def_path = - ty::print::with_forced_impl_filename_line!(tcx.def_path_str(body.source.def_id())); - // ignore-tidy-odd-backticks the literal below is fine - write!(file, "// MIR for `{def_path}")?; - match body.source.promoted { - None => write!(file, "`")?, - Some(promoted) => write!(file, "::{promoted:?}`")?, - } - writeln!(file, " {disambiguator} {pass_name}")?; - if let Some(ref layout) = body.coroutine_layout_raw() { - writeln!(file, "/* coroutine_layout = {layout:#?} */")?; - } - writeln!(file)?; - extra_data(PassWhere::BeforeCFG, &mut file)?; - write_user_type_annotations(tcx, body, &mut file)?; - write_mir_fn(tcx, body, &mut extra_data, &mut file, options)?; - extra_data(PassWhere::AfterCFG, &mut file)?; + dump_mir_to_writer(tcx, pass_name, disambiguator, body, &mut file, extra_data, options)?; }; if tcx.sess.opts.unstable_opts.dump_mir_graphviz { From 3631c15b17e53bd093333cc977dfe0376302a519 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9my=20Rakic?= Date: Fri, 24 Jan 2025 18:19:09 +0000 Subject: [PATCH 41/81] use more explicit MIR dumping process --- compiler/rustc_borrowck/src/polonius/dump.rs | 40 ++++++++++++++++++-- 1 file changed, 36 insertions(+), 4 deletions(-) diff --git a/compiler/rustc_borrowck/src/polonius/dump.rs b/compiler/rustc_borrowck/src/polonius/dump.rs index a6d801490344..b59976dfdfcf 100644 --- a/compiler/rustc_borrowck/src/polonius/dump.rs +++ b/compiler/rustc_borrowck/src/polonius/dump.rs @@ -1,6 +1,8 @@ use std::io; -use rustc_middle::mir::pretty::{PrettyPrintMirOptions, dump_mir_with_options}; +use rustc_middle::mir::pretty::{ + PrettyPrintMirOptions, create_dump_file, dump_enabled, dump_mir_to_writer, +}; use rustc_middle::mir::{Body, ClosureRegionRequirements, PassWhere}; use rustc_middle::ty::TyCtxt; use rustc_session::config::MirIncludeSpans; @@ -26,9 +28,39 @@ pub(crate) fn dump_polonius_mir<'tcx>( return; } + if !dump_enabled(tcx, "polonius", body.source.def_id()) { + return; + } + let localized_outlives_constraints = localized_outlives_constraints .expect("missing localized constraints with `-Zpolonius=next`"); + let _: io::Result<()> = try { + let mut file = create_dump_file(tcx, "mir", false, "polonius", &0, body)?; + emit_polonius_dump( + tcx, + body, + regioncx, + borrow_set, + localized_outlives_constraints, + closure_region_requirements, + &mut file, + )?; + }; +} + +/// The polonius dump consists of: +/// - the NLL MIR +/// - the list of polonius localized constraints +fn emit_polonius_dump<'tcx>( + tcx: TyCtxt<'tcx>, + body: &Body<'tcx>, + regioncx: &RegionInferenceContext<'tcx>, + borrow_set: &BorrowSet<'tcx>, + localized_outlives_constraints: LocalizedOutlivesConstraintSet, + closure_region_requirements: &Option>, + out: &mut dyn io::Write, +) -> io::Result<()> { // We want the NLL extra comments printed by default in NLL MIR dumps (they were removed in // #112346). Specifying `-Z mir-include-spans` on the CLI still has priority: for example, // they're always disabled in mir-opt tests to make working with blessed dumps easier. @@ -39,12 +71,12 @@ pub(crate) fn dump_polonius_mir<'tcx>( ), }; - dump_mir_with_options( + dump_mir_to_writer( tcx, - false, "polonius", &0, body, + out, |pass_where, out| { emit_polonius_mir( tcx, @@ -57,7 +89,7 @@ pub(crate) fn dump_polonius_mir<'tcx>( ) }, options, - ); + ) } /// Produces the actual NLL + Polonius MIR sections to emit during the dumping process. From 6baa65e36659b5f4fe1cdfa94acf2aa9ba98f786 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9my=20Rakic?= Date: Fri, 24 Jan 2025 21:28:16 +0000 Subject: [PATCH 42/81] switch polonius MIR dump to HTML escape the regular raw MIR into its own section --- compiler/rustc_borrowck/src/polonius/dump.rs | 76 +++++++++++++++++--- 1 file changed, 67 insertions(+), 9 deletions(-) diff --git a/compiler/rustc_borrowck/src/polonius/dump.rs b/compiler/rustc_borrowck/src/polonius/dump.rs index b59976dfdfcf..25191fd34979 100644 --- a/compiler/rustc_borrowck/src/polonius/dump.rs +++ b/compiler/rustc_borrowck/src/polonius/dump.rs @@ -12,9 +12,6 @@ use crate::polonius::{LocalizedOutlivesConstraint, LocalizedOutlivesConstraintSe use crate::{BorrowckInferCtxt, RegionInferenceContext}; /// `-Zdump-mir=polonius` dumps MIR annotated with NLL and polonius specific information. -// Note: this currently duplicates most of NLL MIR, with some additions for the localized outlives -// constraints. This is ok for now as this dump will change in the near future to an HTML file to -// become more useful. pub(crate) fn dump_polonius_mir<'tcx>( infcx: &BorrowckInferCtxt<'tcx>, body: &Body<'tcx>, @@ -36,7 +33,7 @@ pub(crate) fn dump_polonius_mir<'tcx>( .expect("missing localized constraints with `-Zpolonius=next`"); let _: io::Result<()> = try { - let mut file = create_dump_file(tcx, "mir", false, "polonius", &0, body)?; + let mut file = create_dump_file(tcx, "html", false, "polonius", &0, body)?; emit_polonius_dump( tcx, body, @@ -61,9 +58,50 @@ fn emit_polonius_dump<'tcx>( closure_region_requirements: &Option>, out: &mut dyn io::Write, ) -> io::Result<()> { - // We want the NLL extra comments printed by default in NLL MIR dumps (they were removed in - // #112346). Specifying `-Z mir-include-spans` on the CLI still has priority: for example, - // they're always disabled in mir-opt tests to make working with blessed dumps easier. + // Prepare the HTML dump file prologue. + writeln!(out, "")?; + writeln!(out, "")?; + writeln!(out, "Polonius MIR dump")?; + writeln!(out, "")?; + + // Section 1: the NLL + Polonius MIR. + writeln!(out, "
")?; + writeln!(out, "Raw MIR dump")?; + writeln!(out, "
")?;
+    emit_html_mir(
+        tcx,
+        body,
+        regioncx,
+        borrow_set,
+        localized_outlives_constraints,
+        closure_region_requirements,
+        out,
+    )?;
+    writeln!(out, "
")?; + writeln!(out, "
")?; + + // Finalize the dump with the HTML epilogue. + writeln!(out, "")?; + writeln!(out, "")?; + + Ok(()) +} + +/// Emits the polonius MIR, as escaped HTML. +fn emit_html_mir<'tcx>( + tcx: TyCtxt<'tcx>, + body: &Body<'tcx>, + regioncx: &RegionInferenceContext<'tcx>, + borrow_set: &BorrowSet<'tcx>, + localized_outlives_constraints: LocalizedOutlivesConstraintSet, + closure_region_requirements: &Option>, + out: &mut dyn io::Write, +) -> io::Result<()> { + // Buffer the regular MIR dump to be able to escape it. + let mut buffer = Vec::new(); + + // We want the NLL extra comments printed by default in NLL MIR dumps. Specifying `-Z + // mir-include-spans` on the CLI still has priority. let options = PrettyPrintMirOptions { include_extra_comments: matches!( tcx.sess.opts.unstable_opts.mir_include_spans, @@ -76,7 +114,7 @@ fn emit_polonius_dump<'tcx>( "polonius", &0, body, - out, + &mut buffer, |pass_where, out| { emit_polonius_mir( tcx, @@ -89,7 +127,27 @@ fn emit_polonius_dump<'tcx>( ) }, options, - ) + )?; + + // Escape the handful of characters that need it. We don't need to be particularly efficient: + // we're actually writing into a buffered writer already. Note that MIR dumps are valid UTF-8. + let buffer = String::from_utf8_lossy(&buffer); + for ch in buffer.chars() { + let escaped = match ch { + '>' => ">", + '<' => "<", + '&' => "&", + '\'' => "'", + '"' => """, + _ => { + // The common case, no escaping needed. + write!(out, "{}", ch)?; + continue; + } + }; + write!(out, "{}", escaped)?; + } + Ok(()) } /// Produces the actual NLL + Polonius MIR sections to emit during the dumping process. From 82c016846e0675df214f55be02d444037b322423 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9my=20Rakic?= Date: Fri, 24 Jan 2025 22:04:18 +0000 Subject: [PATCH 43/81] fix terminator edges comments --- compiler/rustc_middle/src/mir/terminator.rs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_middle/src/mir/terminator.rs b/compiler/rustc_middle/src/mir/terminator.rs index 473b817aed07..c04a8251fbc5 100644 --- a/compiler/rustc_middle/src/mir/terminator.rs +++ b/compiler/rustc_middle/src/mir/terminator.rs @@ -581,9 +581,11 @@ impl<'tcx> TerminatorKind<'tcx> { pub enum TerminatorEdges<'mir, 'tcx> { /// For terminators that have no successor, like `return`. None, - /// For terminators that a single successor, like `goto`, and `assert` without cleanup block. + /// For terminators that have a single successor, like `goto`, and `assert` without a cleanup + /// block. Single(BasicBlock), - /// For terminators that two successors, `assert` with cleanup block and `falseEdge`. + /// For terminators that have two successors, like `assert` with a cleanup block, and + /// `falseEdge`. Double(BasicBlock, BasicBlock), /// Special action for `Yield`, `Call` and `InlineAsm` terminators. AssignOnReturn { From 09fb70afb9dc64278f13be78e2f740fdc3c4d80e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9my=20Rakic?= Date: Fri, 24 Jan 2025 22:04:37 +0000 Subject: [PATCH 44/81] add CFG to polonius MIR dump --- compiler/rustc_borrowck/src/polonius/dump.rs | 73 +++++++++++++++++++- 1 file changed, 71 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_borrowck/src/polonius/dump.rs b/compiler/rustc_borrowck/src/polonius/dump.rs index 25191fd34979..40e801d03885 100644 --- a/compiler/rustc_borrowck/src/polonius/dump.rs +++ b/compiler/rustc_borrowck/src/polonius/dump.rs @@ -1,9 +1,9 @@ use std::io; use rustc_middle::mir::pretty::{ - PrettyPrintMirOptions, create_dump_file, dump_enabled, dump_mir_to_writer, + PassWhere, PrettyPrintMirOptions, create_dump_file, dump_enabled, dump_mir_to_writer, }; -use rustc_middle::mir::{Body, ClosureRegionRequirements, PassWhere}; +use rustc_middle::mir::{Body, ClosureRegionRequirements}; use rustc_middle::ty::TyCtxt; use rustc_session::config::MirIncludeSpans; @@ -49,6 +49,7 @@ pub(crate) fn dump_polonius_mir<'tcx>( /// The polonius dump consists of: /// - the NLL MIR /// - the list of polonius localized constraints +/// - a mermaid graph of the CFG fn emit_polonius_dump<'tcx>( tcx: TyCtxt<'tcx>, body: &Body<'tcx>, @@ -80,7 +81,23 @@ fn emit_polonius_dump<'tcx>( writeln!(out, "")?; writeln!(out, "

")?; + // Section 2: mermaid visualization of the CFG. + writeln!(out, "
")?; + writeln!(out, "Control-flow graph")?; + writeln!(out, "
")?;
+    emit_mermaid_cfg(body, out)?;
+    writeln!(out, "
")?; + writeln!(out, "
")?; + // Finalize the dump with the HTML epilogue. + writeln!( + out, + "" + )?; + writeln!(out, "")?; writeln!(out, "")?; writeln!(out, "")?; @@ -192,3 +209,55 @@ fn emit_polonius_mir<'tcx>( Ok(()) } + +/// Emits a mermaid flowchart of the CFG blocks and edges, similar to the graphviz version. +fn emit_mermaid_cfg(body: &Body<'_>, out: &mut dyn io::Write) -> io::Result<()> { + use rustc_middle::mir::{TerminatorEdges, TerminatorKind}; + + // The mermaid chart type: a top-down flowchart. + writeln!(out, "flowchart TD")?; + + // Emit the block nodes. + for (block_idx, block) in body.basic_blocks.iter_enumerated() { + let block_idx = block_idx.as_usize(); + let cleanup = if block.is_cleanup { " (cleanup)" } else { "" }; + writeln!(out, "{block_idx}[\"bb{block_idx}{cleanup}\"]")?; + } + + // Emit the edges between blocks, from the terminator edges. + for (block_idx, block) in body.basic_blocks.iter_enumerated() { + let block_idx = block_idx.as_usize(); + let terminator = block.terminator(); + match terminator.edges() { + TerminatorEdges::None => {} + TerminatorEdges::Single(bb) => { + writeln!(out, "{block_idx} --> {}", bb.as_usize())?; + } + TerminatorEdges::Double(bb1, bb2) => { + if matches!(terminator.kind, TerminatorKind::FalseEdge { .. }) { + writeln!(out, "{block_idx} --> {}", bb1.as_usize())?; + writeln!(out, "{block_idx} -- imaginary --> {}", bb2.as_usize())?; + } else { + writeln!(out, "{block_idx} --> {}", bb1.as_usize())?; + writeln!(out, "{block_idx} -- unwind --> {}", bb2.as_usize())?; + } + } + TerminatorEdges::AssignOnReturn { return_, cleanup, .. } => { + for to_idx in return_ { + writeln!(out, "{block_idx} --> {}", to_idx.as_usize())?; + } + + if let Some(to_idx) = cleanup { + writeln!(out, "{block_idx} -- unwind --> {}", to_idx.as_usize())?; + } + } + TerminatorEdges::SwitchInt { targets, .. } => { + for to_idx in targets.all_targets() { + writeln!(out, "{block_idx} --> {}", to_idx.as_usize())?; + } + } + } + } + + Ok(()) +} From 6bdc8778db7932aab8332657b19087d4476855c1 Mon Sep 17 00:00:00 2001 From: Luca Versari Date: Sat, 25 Jan 2025 21:36:40 +0100 Subject: [PATCH 45/81] Add a suggestion to cast target_feature fn items to fn pointers. See https://github.com/rust-lang/rust/pull/134090#issuecomment-2612197095 for the motivation behind this suggestion. --- .../traits/fulfillment_errors.rs | 3 ++ .../rfc-2396-target_feature-11/fn-traits.rs | 8 +++ .../fn-traits.stderr | 49 ++++++++++++++----- 3 files changed, 47 insertions(+), 13 deletions(-) diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs index 961719f263c5..5021fd8bf833 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs @@ -462,6 +462,9 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { err.note( "`#[target_feature]` functions do not implement the `Fn` traits", ); + err.note( + "try casting the function to a `fn` pointer or wrapping it in a closure", + ); } self.try_to_add_help_message( diff --git a/tests/ui/rfcs/rfc-2396-target_feature-11/fn-traits.rs b/tests/ui/rfcs/rfc-2396-target_feature-11/fn-traits.rs index 3eae79faf423..c880ef0fe8a0 100644 --- a/tests/ui/rfcs/rfc-2396-target_feature-11/fn-traits.rs +++ b/tests/ui/rfcs/rfc-2396-target_feature-11/fn-traits.rs @@ -5,6 +5,9 @@ #[target_feature(enable = "avx")] fn foo() {} +#[target_feature(enable = "avx")] +fn bar(arg: i32) {} + #[target_feature(enable = "avx")] unsafe fn foo_unsafe() {} @@ -20,10 +23,15 @@ fn call_once(f: impl FnOnce()) { f() } +fn call_once_i32(f: impl FnOnce(i32)) { + f(0) +} + fn main() { call(foo); //~ ERROR expected a `Fn()` closure, found `#[target_features] fn() {foo}` call_mut(foo); //~ ERROR expected a `FnMut()` closure, found `#[target_features] fn() {foo}` call_once(foo); //~ ERROR expected a `FnOnce()` closure, found `#[target_features] fn() {foo}` + call_once_i32(bar); //~ ERROR expected a `FnOnce(i32)` closure, found `#[target_features] fn(i32) {bar}` call(foo_unsafe); //~^ ERROR expected a `Fn()` closure, found `unsafe fn() {foo_unsafe}` diff --git a/tests/ui/rfcs/rfc-2396-target_feature-11/fn-traits.stderr b/tests/ui/rfcs/rfc-2396-target_feature-11/fn-traits.stderr index 2915b9ad1b3d..efc061eca5f5 100644 --- a/tests/ui/rfcs/rfc-2396-target_feature-11/fn-traits.stderr +++ b/tests/ui/rfcs/rfc-2396-target_feature-11/fn-traits.stderr @@ -1,5 +1,5 @@ error[E0277]: expected a `Fn()` closure, found `#[target_features] fn() {foo}` - --> $DIR/fn-traits.rs:24:10 + --> $DIR/fn-traits.rs:31:10 | LL | call(foo); | ---- ^^^ expected an `Fn()` closure, found `#[target_features] fn() {foo}` @@ -9,14 +9,15 @@ LL | call(foo); = help: the trait `Fn()` is not implemented for fn item `#[target_features] fn() {foo}` = note: wrap the `#[target_features] fn() {foo}` in a closure with no arguments: `|| { /* code */ }` = note: `#[target_feature]` functions do not implement the `Fn` traits + = note: try casting the function to a `fn` pointer or wrapping it in a closure note: required by a bound in `call` - --> $DIR/fn-traits.rs:11:17 + --> $DIR/fn-traits.rs:14:17 | LL | fn call(f: impl Fn()) { | ^^^^ required by this bound in `call` error[E0277]: expected a `FnMut()` closure, found `#[target_features] fn() {foo}` - --> $DIR/fn-traits.rs:25:14 + --> $DIR/fn-traits.rs:32:14 | LL | call_mut(foo); | -------- ^^^ expected an `FnMut()` closure, found `#[target_features] fn() {foo}` @@ -26,14 +27,15 @@ LL | call_mut(foo); = help: the trait `FnMut()` is not implemented for fn item `#[target_features] fn() {foo}` = note: wrap the `#[target_features] fn() {foo}` in a closure with no arguments: `|| { /* code */ }` = note: `#[target_feature]` functions do not implement the `Fn` traits + = note: try casting the function to a `fn` pointer or wrapping it in a closure note: required by a bound in `call_mut` - --> $DIR/fn-traits.rs:15:25 + --> $DIR/fn-traits.rs:18:25 | LL | fn call_mut(mut f: impl FnMut()) { | ^^^^^^^ required by this bound in `call_mut` error[E0277]: expected a `FnOnce()` closure, found `#[target_features] fn() {foo}` - --> $DIR/fn-traits.rs:26:15 + --> $DIR/fn-traits.rs:33:15 | LL | call_once(foo); | --------- ^^^ expected an `FnOnce()` closure, found `#[target_features] fn() {foo}` @@ -43,14 +45,32 @@ LL | call_once(foo); = help: the trait `FnOnce()` is not implemented for fn item `#[target_features] fn() {foo}` = note: wrap the `#[target_features] fn() {foo}` in a closure with no arguments: `|| { /* code */ }` = note: `#[target_feature]` functions do not implement the `Fn` traits + = note: try casting the function to a `fn` pointer or wrapping it in a closure note: required by a bound in `call_once` - --> $DIR/fn-traits.rs:19:22 + --> $DIR/fn-traits.rs:22:22 | LL | fn call_once(f: impl FnOnce()) { | ^^^^^^^^ required by this bound in `call_once` +error[E0277]: expected a `FnOnce(i32)` closure, found `#[target_features] fn(i32) {bar}` + --> $DIR/fn-traits.rs:34:19 + | +LL | call_once_i32(bar); + | ------------- ^^^ expected an `FnOnce(i32)` closure, found `#[target_features] fn(i32) {bar}` + | | + | required by a bound introduced by this call + | + = help: the trait `FnOnce(i32)` is not implemented for fn item `#[target_features] fn(i32) {bar}` + = note: `#[target_feature]` functions do not implement the `Fn` traits + = note: try casting the function to a `fn` pointer or wrapping it in a closure +note: required by a bound in `call_once_i32` + --> $DIR/fn-traits.rs:26:26 + | +LL | fn call_once_i32(f: impl FnOnce(i32)) { + | ^^^^^^^^^^^ required by this bound in `call_once_i32` + error[E0277]: expected a `Fn()` closure, found `unsafe fn() {foo_unsafe}` - --> $DIR/fn-traits.rs:28:10 + --> $DIR/fn-traits.rs:36:10 | LL | call(foo_unsafe); | ---- ^^^^^^^^^^ call the function in a closure: `|| unsafe { /* code */ }` @@ -61,14 +81,15 @@ LL | call(foo_unsafe); = note: unsafe function cannot be called generically without an unsafe block = note: wrap the `unsafe fn() {foo_unsafe}` in a closure with no arguments: `|| { /* code */ }` = note: `#[target_feature]` functions do not implement the `Fn` traits + = note: try casting the function to a `fn` pointer or wrapping it in a closure note: required by a bound in `call` - --> $DIR/fn-traits.rs:11:17 + --> $DIR/fn-traits.rs:14:17 | LL | fn call(f: impl Fn()) { | ^^^^ required by this bound in `call` error[E0277]: expected a `FnMut()` closure, found `unsafe fn() {foo_unsafe}` - --> $DIR/fn-traits.rs:30:14 + --> $DIR/fn-traits.rs:38:14 | LL | call_mut(foo_unsafe); | -------- ^^^^^^^^^^ call the function in a closure: `|| unsafe { /* code */ }` @@ -79,14 +100,15 @@ LL | call_mut(foo_unsafe); = note: unsafe function cannot be called generically without an unsafe block = note: wrap the `unsafe fn() {foo_unsafe}` in a closure with no arguments: `|| { /* code */ }` = note: `#[target_feature]` functions do not implement the `Fn` traits + = note: try casting the function to a `fn` pointer or wrapping it in a closure note: required by a bound in `call_mut` - --> $DIR/fn-traits.rs:15:25 + --> $DIR/fn-traits.rs:18:25 | LL | fn call_mut(mut f: impl FnMut()) { | ^^^^^^^ required by this bound in `call_mut` error[E0277]: expected a `FnOnce()` closure, found `unsafe fn() {foo_unsafe}` - --> $DIR/fn-traits.rs:32:15 + --> $DIR/fn-traits.rs:40:15 | LL | call_once(foo_unsafe); | --------- ^^^^^^^^^^ call the function in a closure: `|| unsafe { /* code */ }` @@ -97,12 +119,13 @@ LL | call_once(foo_unsafe); = note: unsafe function cannot be called generically without an unsafe block = note: wrap the `unsafe fn() {foo_unsafe}` in a closure with no arguments: `|| { /* code */ }` = note: `#[target_feature]` functions do not implement the `Fn` traits + = note: try casting the function to a `fn` pointer or wrapping it in a closure note: required by a bound in `call_once` - --> $DIR/fn-traits.rs:19:22 + --> $DIR/fn-traits.rs:22:22 | LL | fn call_once(f: impl FnOnce()) { | ^^^^^^^^ required by this bound in `call_once` -error: aborting due to 6 previous errors +error: aborting due to 7 previous errors For more information about this error, try `rustc --explain E0277`. From fb500c34ea5e896e4ea170a274cdb28dae2261aa Mon Sep 17 00:00:00 2001 From: cyrgani Date: Sat, 25 Jan 2025 23:40:35 +0100 Subject: [PATCH 46/81] add two old crash tests --- tests/crashes/108428.rs | 6 ++++++ tests/crashes/132826.rs | 10 ++++++++++ 2 files changed, 16 insertions(+) create mode 100644 tests/crashes/108428.rs create mode 100644 tests/crashes/132826.rs diff --git a/tests/crashes/108428.rs b/tests/crashes/108428.rs new file mode 100644 index 000000000000..b18123b6a7c4 --- /dev/null +++ b/tests/crashes/108428.rs @@ -0,0 +1,6 @@ +//@ known-bug: #108428 +//@ needs-rustc-debug-assertions +//@ compile-flags: -Wunused-lifetimes +fn main() { + let _: extern fn<'a: 'static>(); +} diff --git a/tests/crashes/132826.rs b/tests/crashes/132826.rs new file mode 100644 index 000000000000..9889cecdac54 --- /dev/null +++ b/tests/crashes/132826.rs @@ -0,0 +1,10 @@ +//@ known-bug: #132826 +pub trait MyTrait { + type Item; +} + +impl MyTrait for Vec { + type Item = Vec; +} + +impl From> for as MyTrait>::Item {} From d36e2b88d643b3d712c6e2d22b4b0d77fea07209 Mon Sep 17 00:00:00 2001 From: Zalathar Date: Sun, 26 Jan 2025 14:00:46 +1100 Subject: [PATCH 47/81] Incorporate `iter_nodes` into `graph::DirectedGraph` This assumes that the set of valid node IDs is exactly `0..num_nodes`. In practice, we have a lot of graph-algorithm code that already assumes that nodes are densely numbered, by using `num_nodes` to allocate per-node indexed data structures. --- compiler/rustc_data_structures/src/graph/mod.rs | 16 ++++++++++++++++ .../rustc_data_structures/src/graph/scc/mod.rs | 4 ++-- .../rustc_mir_transform/src/coverage/counters.rs | 2 -- .../src/coverage/counters/balanced_flow.rs | 2 -- .../src/coverage/counters/iter_nodes.rs | 16 ---------------- .../src/coverage/counters/node_flow.rs | 1 - 6 files changed, 18 insertions(+), 23 deletions(-) delete mode 100644 compiler/rustc_mir_transform/src/coverage/counters/iter_nodes.rs diff --git a/compiler/rustc_data_structures/src/graph/mod.rs b/compiler/rustc_data_structures/src/graph/mod.rs index 92035e8bc480..4a1e5db6768d 100644 --- a/compiler/rustc_data_structures/src/graph/mod.rs +++ b/compiler/rustc_data_structures/src/graph/mod.rs @@ -14,7 +14,23 @@ mod tests; pub trait DirectedGraph { type Node: Idx; + /// Returns the total number of nodes in this graph. + /// + /// Several graph algorithm implementations assume that every node ID is + /// strictly less than the number of nodes, i.e. nodes are densely numbered. + /// That assumption allows them to use `num_nodes` to allocate per-node + /// data structures, indexed by node. fn num_nodes(&self) -> usize; + + /// Iterates over all nodes of a graph in ascending numeric order. + /// + /// Assumes that nodes are densely numbered, i.e. every index in + /// `0..num_nodes` is a valid node. + fn iter_nodes( + &self, + ) -> impl Iterator + DoubleEndedIterator + ExactSizeIterator { + (0..self.num_nodes()).map(::new) + } } pub trait NumEdges: DirectedGraph { diff --git a/compiler/rustc_data_structures/src/graph/scc/mod.rs b/compiler/rustc_data_structures/src/graph/scc/mod.rs index 06fedef00fc3..93f6192b10b0 100644 --- a/compiler/rustc_data_structures/src/graph/scc/mod.rs +++ b/compiler/rustc_data_structures/src/graph/scc/mod.rs @@ -333,8 +333,8 @@ where to_annotation, }; - let scc_indices = (0..num_nodes) - .map(G::Node::new) + let scc_indices = graph + .iter_nodes() .map(|node| match this.start_walk_from(node) { WalkReturn::Complete { scc_index, .. } => scc_index, WalkReturn::Cycle { min_depth, .. } => { diff --git a/compiler/rustc_mir_transform/src/coverage/counters.rs b/compiler/rustc_mir_transform/src/coverage/counters.rs index 50ebde3292ea..adb99a75a9e4 100644 --- a/compiler/rustc_mir_transform/src/coverage/counters.rs +++ b/compiler/rustc_mir_transform/src/coverage/counters.rs @@ -10,14 +10,12 @@ use rustc_index::bit_set::DenseBitSet; use rustc_middle::mir::coverage::{CounterId, CovTerm, Expression, ExpressionId, Op}; use crate::coverage::counters::balanced_flow::BalancedFlowGraph; -use crate::coverage::counters::iter_nodes::IterNodes; use crate::coverage::counters::node_flow::{ CounterTerm, NodeCounters, make_node_counters, node_flow_data_for_balanced_graph, }; use crate::coverage::graph::{BasicCoverageBlock, CoverageGraph}; mod balanced_flow; -mod iter_nodes; mod node_flow; mod union_find; diff --git a/compiler/rustc_mir_transform/src/coverage/counters/balanced_flow.rs b/compiler/rustc_mir_transform/src/coverage/counters/balanced_flow.rs index c108f96a564c..4c20722a0434 100644 --- a/compiler/rustc_mir_transform/src/coverage/counters/balanced_flow.rs +++ b/compiler/rustc_mir_transform/src/coverage/counters/balanced_flow.rs @@ -20,8 +20,6 @@ use rustc_data_structures::graph::reversed::ReversedGraph; use rustc_index::Idx; use rustc_index::bit_set::DenseBitSet; -use crate::coverage::counters::iter_nodes::IterNodes; - /// A view of an underlying graph that has been augmented to have “balanced flow”. /// This means that the flow (execution count) of each node is equal to the /// sum of its in-edge flows, and also equal to the sum of its out-edge flows. diff --git a/compiler/rustc_mir_transform/src/coverage/counters/iter_nodes.rs b/compiler/rustc_mir_transform/src/coverage/counters/iter_nodes.rs deleted file mode 100644 index 9d87f7af1b04..000000000000 --- a/compiler/rustc_mir_transform/src/coverage/counters/iter_nodes.rs +++ /dev/null @@ -1,16 +0,0 @@ -use rustc_data_structures::graph; -use rustc_index::Idx; - -pub(crate) trait IterNodes: graph::DirectedGraph { - /// Iterates over all nodes of a graph in ascending numeric order. - /// Assumes that nodes are densely numbered, i.e. every index in - /// `0..num_nodes` is a valid node. - /// - /// FIXME: Can this just be part of [`graph::DirectedGraph`]? - fn iter_nodes( - &self, - ) -> impl Iterator + DoubleEndedIterator + ExactSizeIterator { - (0..self.num_nodes()).map(::new) - } -} -impl IterNodes for G {} diff --git a/compiler/rustc_mir_transform/src/coverage/counters/node_flow.rs b/compiler/rustc_mir_transform/src/coverage/counters/node_flow.rs index 3647c8899374..9d80b3af42d8 100644 --- a/compiler/rustc_mir_transform/src/coverage/counters/node_flow.rs +++ b/compiler/rustc_mir_transform/src/coverage/counters/node_flow.rs @@ -11,7 +11,6 @@ use rustc_index::bit_set::DenseBitSet; use rustc_index::{Idx, IndexSlice, IndexVec}; use rustc_middle::mir::coverage::Op; -use crate::coverage::counters::iter_nodes::IterNodes; use crate::coverage::counters::union_find::UnionFind; #[cfg(test)] From b3a5d0a5f4c7a604f742d4d9d7806a71af2cbd48 Mon Sep 17 00:00:00 2001 From: Jacob Pratt Date: Tue, 21 Jan 2025 08:45:03 +0000 Subject: [PATCH 48/81] Implement phantom variance markers --- library/core/src/marker.rs | 7 + library/core/src/marker/variance.rs | 260 ++++++++++++++++++++++++++++ 2 files changed, 267 insertions(+) create mode 100644 library/core/src/marker/variance.rs diff --git a/library/core/src/marker.rs b/library/core/src/marker.rs index 01af964a83e2..a793fc2aa2e5 100644 --- a/library/core/src/marker.rs +++ b/library/core/src/marker.rs @@ -6,6 +6,13 @@ #![stable(feature = "rust1", since = "1.0.0")] +mod variance; + +#[unstable(feature = "phantom_variance_markers", issue = "135806")] +pub use self::variance::{ + PhantomContravariant, PhantomContravariantLifetime, PhantomCovariant, PhantomCovariantLifetime, + PhantomInvariant, PhantomInvariantLifetime, Variance, variance, +}; use crate::cell::UnsafeCell; use crate::cmp; use crate::fmt::Debug; diff --git a/library/core/src/marker/variance.rs b/library/core/src/marker/variance.rs new file mode 100644 index 000000000000..23334e6575dd --- /dev/null +++ b/library/core/src/marker/variance.rs @@ -0,0 +1,260 @@ +#![unstable(feature = "phantom_variance_markers", issue = "135806")] + +use super::PhantomData; +use crate::any::type_name; +use crate::cmp::Ordering; +use crate::fmt; +use crate::hash::{Hash, Hasher}; + +macro_rules! first_token { + ($first:tt $($rest:tt)*) => { + $first + }; +} + +macro_rules! phantom_type { + ($( + $(#[$attr:meta])* + pub struct $name:ident <$t:ident> ($($inner:tt)*); + )*) => {$( + $(#[$attr])* + pub struct $name<$t>($($inner)*) where T: ?Sized; + + impl $name + where T: ?Sized + { + /// Constructs a new instance of the variance marker. + pub const fn new() -> Self { + Self(PhantomData) + } + } + + impl self::sealed::Sealed for $name where T: ?Sized { + const VALUE: Self = Self::new(); + } + impl Variance for $name where T: ?Sized {} + + impl Default for $name + where T: ?Sized + { + fn default() -> Self { + Self(PhantomData) + } + } + + impl fmt::Debug for $name + where T: ?Sized + { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "{}<{}>", stringify!($name), type_name::()) + } + } + + impl Clone for $name + where T: ?Sized + { + fn clone(&self) -> Self { + *self + } + } + + impl Copy for $name where T: ?Sized {} + + impl PartialEq for $name + where T: ?Sized + { + fn eq(&self, _: &Self) -> bool { + true + } + } + + impl Eq for $name where T: ?Sized {} + + impl PartialOrd for $name + where T: ?Sized + { + fn partial_cmp(&self, _: &Self) -> Option { + Some(Ordering::Equal) + } + } + + impl Ord for $name + where T: ?Sized + { + fn cmp(&self, _: &Self) -> Ordering { + Ordering::Equal + } + } + + impl Hash for $name + where T: ?Sized + { + fn hash(&self, _: &mut H) {} + } + )*}; +} + +macro_rules! phantom_lifetime { + ($( + $(#[$attr:meta])* + pub struct $name:ident <$lt:lifetime> ($($inner:tt)*); + )*) => {$( + $(#[$attr])* + #[derive(Default, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] + pub struct $name<$lt>($($inner)*); + + impl $name<'_> { + /// Constructs a new instance of the variance marker. + pub const fn new() -> Self { + Self(first_token!($($inner)*)(PhantomData)) + } + } + + impl self::sealed::Sealed for $name<'_> { + const VALUE: Self = Self::new(); + } + impl Variance for $name<'_> {} + + impl fmt::Debug for $name<'_> { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "{}", stringify!($name)) + } + } + )*}; +} + +phantom_lifetime! { + /// Zero-sized type used to mark a lifetime as covariant. + /// + /// Covariant lifetimes must live at least as long as declared. See [the reference][1] for more + /// information. + /// + /// [1]: https://doc.rust-lang.org/stable/reference/subtyping.html#variance + /// + /// ## Layout + /// + /// For all `'a`, the following are guaranteed: + /// * `size_of::>() == 0` + /// * `align_of::>() == 1` + pub struct PhantomCovariantLifetime<'a>(PhantomCovariant<&'a ()>); + /// Zero-sized type used to mark a lifetime as contravariant. + /// + /// Contravariant lifetimes must live at most as long as declared. See [the reference][1] for + /// more information. + /// + /// [1]: https://doc.rust-lang.org/stable/reference/subtyping.html#variance + /// + /// ## Layout + /// + /// For all `'a`, the following are guaranteed: + /// * `size_of::>() == 0` + /// * `align_of::>() == 1` + pub struct PhantomContravariantLifetime<'a>(PhantomContravariant<&'a ()>); + /// Zero-sized type used to mark a lifetime as invariant. + /// + /// Invariant lifetimes must be live for the exact length declared, neither shorter nor longer. + /// See [the reference][1] for more information. + /// + /// [1]: https://doc.rust-lang.org/stable/reference/subtyping.html#variance + /// + /// ## Layout + /// + /// For all `'a`, the following are guaranteed: + /// * `size_of::>() == 0` + /// * `align_of::>() == 1` + pub struct PhantomInvariantLifetime<'a>(PhantomInvariant<&'a ()>); +} + +phantom_type! { + /// Zero-sized type used to mark a type parameter as covariant. + /// + /// Types used as part of the return value from a function are covariant. If the type is _also_ + /// passed as a parameter then it is [invariant][PhantomInvariant]. See [the reference][1] for + /// more information. + /// + /// [1]: https://doc.rust-lang.org/stable/reference/subtyping.html#variance + /// + /// ## Layout + /// + /// For all `T`, the following are guaranteed: + /// * `size_of::>() == 0` + /// * `align_of::>() == 1` + pub struct PhantomCovariant(PhantomData T>); + /// Zero-sized type used to mark a type parameter as contravariant. + /// + /// Types passed as arguments to a function are contravariant. If the type is _also_ part of the + /// return value from a function then it is [invariant][PhantomInvariant]. See [the + /// reference][1] for more information. + /// + /// [1]: https://doc.rust-lang.org/stable/reference/subtyping.html#variance + /// + /// ## Layout + /// + /// For all `T`, the following are guaranteed: + /// * `size_of::>() == 0` + /// * `align_of::>() == 1` + pub struct PhantomContravariant(PhantomData); + /// Zero-sized type used to mark a type parameter as invariant. + /// + /// Types that are both passed as an argument _and_ used as part of the return value from a + /// function are invariant. See [the reference][1] for more information. + /// + /// [1]: https://doc.rust-lang.org/stable/reference/subtyping.html#variance + /// + /// ## Layout + /// + /// For all `T`, the following are guaranteed: + /// * `size_of::>() == 0` + /// * `align_of::>() == 1` + pub struct PhantomInvariant(PhantomData T>); +} + +mod sealed { + pub trait Sealed { + const VALUE: Self; + } +} + +/// A marker trait for phantom variance types. +pub trait Variance: sealed::Sealed + Default {} + +/// Construct a variance marker; equivalent to [`Default::default`]. +/// +/// This type can be any of the following. You generally should not need to explicitly name the +/// type, however. +/// +/// - [`PhantomCovariant`] +/// - [`PhantomContravariant`] +/// - [`PhantomInvariant`] +/// - [`PhantomCovariantLifetime`] +/// - [`PhantomContravariantLifetime`] +/// - [`PhantomInvariantLifetime`] +/// +/// # Example +/// +/// ```rust +/// #![feature(phantom_variance_markers)] +/// +/// use core::marker::{PhantomCovariant, variance}; +/// +/// struct BoundFn +/// where +/// F: Fn(P) -> R, +/// { +/// function: F, +/// parameter: P, +/// return_value: PhantomCovariant, +/// } +/// +/// let bound_fn = BoundFn { +/// function: core::convert::identity, +/// parameter: 5u8, +/// return_value: variance(), +/// }; +/// ``` +pub const fn variance() -> T +where + T: Variance, +{ + T::VALUE +} From b6a384194204f34b70fe738e809848ee274b9681 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Wed, 4 Dec 2024 13:07:14 +0000 Subject: [PATCH 49/81] Put all coretests in a separate crate --- library/Cargo.lock | 4 +++ library/Cargo.toml | 1 + library/core/Cargo.toml | 13 --------- library/coretests/Cargo.toml | 27 +++++++++++++++++++ library/{core => coretests}/benches/any.rs | 0 library/{core => coretests}/benches/array.rs | 0 library/{core => coretests}/benches/ascii.rs | 0 .../benches/ascii/is_ascii.rs | 0 .../benches/char/methods.rs | 0 .../{core => coretests}/benches/char/mod.rs | 0 library/{core => coretests}/benches/fmt.rs | 0 .../{core => coretests}/benches/hash/mod.rs | 0 .../{core => coretests}/benches/hash/sip.rs | 0 library/{core => coretests}/benches/iter.rs | 0 library/{core => coretests}/benches/lib.rs | 0 .../benches/net/addr_parser.rs | 0 .../{core => coretests}/benches/net/mod.rs | 0 .../benches/num/dec2flt/mod.rs | 0 .../benches/num/flt2dec/mod.rs | 0 .../benches/num/flt2dec/strategy/dragon.rs | 0 .../benches/num/flt2dec/strategy/grisu.rs | 0 .../benches/num/int_log/mod.rs | 0 .../benches/num/int_pow/mod.rs | 0 .../benches/num/int_sqrt/mod.rs | 0 .../{core => coretests}/benches/num/mod.rs | 0 library/{core => coretests}/benches/ops.rs | 0 .../{core => coretests}/benches/pattern.rs | 0 library/{core => coretests}/benches/slice.rs | 0 library/{core => coretests}/benches/str.rs | 0 .../benches/str/char_count.rs | 0 .../benches/str/corpora.rs | 0 .../{core => coretests}/benches/str/debug.rs | 0 .../{core => coretests}/benches/str/iter.rs | 0 library/{core => coretests}/benches/tuple.rs | 0 library/coretests/lib.rs | 1 + library/{core => coretests}/tests/alloc.rs | 0 library/{core => coretests}/tests/any.rs | 0 library/{core => coretests}/tests/array.rs | 0 library/{core => coretests}/tests/ascii.rs | 0 .../{core => coretests}/tests/ascii_char.rs | 0 .../{core => coretests}/tests/asserting.rs | 0 .../tests/async_iter/mod.rs | 0 library/{core => coretests}/tests/atomic.rs | 0 library/{core => coretests}/tests/bool.rs | 0 library/{core => coretests}/tests/bstr.rs | 0 library/{core => coretests}/tests/cell.rs | 0 library/{core => coretests}/tests/char.rs | 0 library/{core => coretests}/tests/clone.rs | 0 library/{core => coretests}/tests/cmp.rs | 0 .../{core => coretests}/tests/const_ptr.rs | 0 library/{core => coretests}/tests/convert.rs | 0 library/{core => coretests}/tests/error.rs | 0 library/{core => coretests}/tests/ffi.rs | 0 library/{core => coretests}/tests/ffi/cstr.rs | 0 .../{core => coretests}/tests/fmt/builders.rs | 0 .../{core => coretests}/tests/fmt/float.rs | 0 library/{core => coretests}/tests/fmt/mod.rs | 0 library/{core => coretests}/tests/fmt/num.rs | 0 library/{core => coretests}/tests/future.rs | 0 library/{core => coretests}/tests/hash/mod.rs | 0 library/{core => coretests}/tests/hash/sip.rs | 0 .../{core => coretests}/tests/intrinsics.rs | 0 .../tests/io/borrowed_buf.rs | 0 library/{core => coretests}/tests/io/mod.rs | 0 .../tests/iter/adapters/array_chunks.rs | 0 .../tests/iter/adapters/by_ref_sized.rs | 0 .../tests/iter/adapters/chain.rs | 0 .../tests/iter/adapters/cloned.rs | 0 .../tests/iter/adapters/copied.rs | 0 .../tests/iter/adapters/cycle.rs | 0 .../tests/iter/adapters/enumerate.rs | 0 .../tests/iter/adapters/filter.rs | 0 .../tests/iter/adapters/filter_map.rs | 0 .../tests/iter/adapters/flat_map.rs | 0 .../tests/iter/adapters/flatten.rs | 0 .../tests/iter/adapters/fuse.rs | 0 .../tests/iter/adapters/inspect.rs | 0 .../tests/iter/adapters/intersperse.rs | 0 .../tests/iter/adapters/map.rs | 0 .../tests/iter/adapters/map_windows.rs | 0 .../tests/iter/adapters/mod.rs | 0 .../tests/iter/adapters/peekable.rs | 0 .../tests/iter/adapters/scan.rs | 0 .../tests/iter/adapters/skip.rs | 0 .../tests/iter/adapters/skip_while.rs | 0 .../tests/iter/adapters/step_by.rs | 0 .../tests/iter/adapters/take.rs | 0 .../tests/iter/adapters/take_while.rs | 0 .../tests/iter/adapters/zip.rs | 0 library/{core => coretests}/tests/iter/mod.rs | 0 .../{core => coretests}/tests/iter/range.rs | 0 .../{core => coretests}/tests/iter/sources.rs | 0 .../tests/iter/traits/accum.rs | 0 .../tests/iter/traits/double_ended.rs | 0 .../tests/iter/traits/iterator.rs | 0 .../tests/iter/traits/mod.rs | 0 .../tests/iter/traits/step.rs | 0 library/{core => coretests}/tests/lazy.rs | 0 library/{core => coretests}/tests/lib.rs | 0 library/{core => coretests}/tests/macros.rs | 0 .../tests/macros_bootstrap.rs | 0 .../tests/manually_drop.rs | 0 library/{core => coretests}/tests/mem.rs | 0 .../{core => coretests}/tests/net/ip_addr.rs | 0 library/{core => coretests}/tests/net/mod.rs | 0 .../{core => coretests}/tests/net/parser.rs | 0 .../tests/net/socket_addr.rs | 0 library/{core => coretests}/tests/nonzero.rs | 0 .../{core => coretests}/tests/num/bignum.rs | 0 .../tests/num/const_from.rs | 0 .../tests/num/dec2flt/float.rs | 0 .../tests/num/dec2flt/lemire.rs | 0 .../tests/num/dec2flt/mod.rs | 0 .../tests/num/dec2flt/parse.rs | 0 .../tests/num/float_iter_sum_identity.rs | 0 .../tests/num/flt2dec/estimator.rs | 0 .../tests/num/flt2dec/mod.rs | 0 .../tests/num/flt2dec/random.rs | 0 .../tests/num/flt2dec/strategy/dragon.rs | 0 .../tests/num/flt2dec/strategy/grisu.rs | 0 library/{core => coretests}/tests/num/i128.rs | 0 library/{core => coretests}/tests/num/i16.rs | 0 library/{core => coretests}/tests/num/i32.rs | 0 library/{core => coretests}/tests/num/i64.rs | 0 library/{core => coretests}/tests/num/i8.rs | 0 .../{core => coretests}/tests/num/ieee754.rs | 0 .../{core => coretests}/tests/num/int_log.rs | 0 .../tests/num/int_macros.rs | 0 .../{core => coretests}/tests/num/int_sqrt.rs | 0 .../{core => coretests}/tests/num/midpoint.rs | 0 library/{core => coretests}/tests/num/mod.rs | 0 library/{core => coretests}/tests/num/nan.rs | 0 library/{core => coretests}/tests/num/ops.rs | 0 library/{core => coretests}/tests/num/u128.rs | 0 library/{core => coretests}/tests/num/u16.rs | 0 library/{core => coretests}/tests/num/u32.rs | 0 library/{core => coretests}/tests/num/u64.rs | 0 library/{core => coretests}/tests/num/u8.rs | 0 .../tests/num/uint_macros.rs | 0 .../{core => coretests}/tests/num/wrapping.rs | 0 library/{core => coretests}/tests/ops.rs | 0 .../tests/ops/control_flow.rs | 0 .../tests/ops/from_residual.rs | 0 library/{core => coretests}/tests/option.rs | 0 library/{core => coretests}/tests/panic.rs | 0 .../tests/panic/location.rs | 0 library/{core => coretests}/tests/pattern.rs | 0 library/{core => coretests}/tests/pin.rs | 0 .../{core => coretests}/tests/pin_macro.rs | 0 library/{core => coretests}/tests/ptr.rs | 0 library/{core => coretests}/tests/result.rs | 0 library/{core => coretests}/tests/simd.rs | 0 library/{core => coretests}/tests/slice.rs | 0 library/{core => coretests}/tests/str.rs | 0 .../{core => coretests}/tests/str_lossy.rs | 0 library/{core => coretests}/tests/task.rs | 0 library/{core => coretests}/tests/time.rs | 0 library/{core => coretests}/tests/tuple.rs | 0 library/{core => coretests}/tests/unicode.rs | 0 library/{core => coretests}/tests/waker.rs | 0 src/bootstrap/mk/Makefile.in | 4 +-- src/bootstrap/src/core/build_steps/check.rs | 2 +- src/bootstrap/src/core/build_steps/test.rs | 2 +- 163 files changed, 37 insertions(+), 17 deletions(-) create mode 100644 library/coretests/Cargo.toml rename library/{core => coretests}/benches/any.rs (100%) rename library/{core => coretests}/benches/array.rs (100%) rename library/{core => coretests}/benches/ascii.rs (100%) rename library/{core => coretests}/benches/ascii/is_ascii.rs (100%) rename library/{core => coretests}/benches/char/methods.rs (100%) rename library/{core => coretests}/benches/char/mod.rs (100%) rename library/{core => coretests}/benches/fmt.rs (100%) rename library/{core => coretests}/benches/hash/mod.rs (100%) rename library/{core => coretests}/benches/hash/sip.rs (100%) rename library/{core => coretests}/benches/iter.rs (100%) rename library/{core => coretests}/benches/lib.rs (100%) rename library/{core => coretests}/benches/net/addr_parser.rs (100%) rename library/{core => coretests}/benches/net/mod.rs (100%) rename library/{core => coretests}/benches/num/dec2flt/mod.rs (100%) rename library/{core => coretests}/benches/num/flt2dec/mod.rs (100%) rename library/{core => coretests}/benches/num/flt2dec/strategy/dragon.rs (100%) rename library/{core => coretests}/benches/num/flt2dec/strategy/grisu.rs (100%) rename library/{core => coretests}/benches/num/int_log/mod.rs (100%) rename library/{core => coretests}/benches/num/int_pow/mod.rs (100%) rename library/{core => coretests}/benches/num/int_sqrt/mod.rs (100%) rename library/{core => coretests}/benches/num/mod.rs (100%) rename library/{core => coretests}/benches/ops.rs (100%) rename library/{core => coretests}/benches/pattern.rs (100%) rename library/{core => coretests}/benches/slice.rs (100%) rename library/{core => coretests}/benches/str.rs (100%) rename library/{core => coretests}/benches/str/char_count.rs (100%) rename library/{core => coretests}/benches/str/corpora.rs (100%) rename library/{core => coretests}/benches/str/debug.rs (100%) rename library/{core => coretests}/benches/str/iter.rs (100%) rename library/{core => coretests}/benches/tuple.rs (100%) create mode 100644 library/coretests/lib.rs rename library/{core => coretests}/tests/alloc.rs (100%) rename library/{core => coretests}/tests/any.rs (100%) rename library/{core => coretests}/tests/array.rs (100%) rename library/{core => coretests}/tests/ascii.rs (100%) rename library/{core => coretests}/tests/ascii_char.rs (100%) rename library/{core => coretests}/tests/asserting.rs (100%) rename library/{core => coretests}/tests/async_iter/mod.rs (100%) rename library/{core => coretests}/tests/atomic.rs (100%) rename library/{core => coretests}/tests/bool.rs (100%) rename library/{core => coretests}/tests/bstr.rs (100%) rename library/{core => coretests}/tests/cell.rs (100%) rename library/{core => coretests}/tests/char.rs (100%) rename library/{core => coretests}/tests/clone.rs (100%) rename library/{core => coretests}/tests/cmp.rs (100%) rename library/{core => coretests}/tests/const_ptr.rs (100%) rename library/{core => coretests}/tests/convert.rs (100%) rename library/{core => coretests}/tests/error.rs (100%) rename library/{core => coretests}/tests/ffi.rs (100%) rename library/{core => coretests}/tests/ffi/cstr.rs (100%) rename library/{core => coretests}/tests/fmt/builders.rs (100%) rename library/{core => coretests}/tests/fmt/float.rs (100%) rename library/{core => coretests}/tests/fmt/mod.rs (100%) rename library/{core => coretests}/tests/fmt/num.rs (100%) rename library/{core => coretests}/tests/future.rs (100%) rename library/{core => coretests}/tests/hash/mod.rs (100%) rename library/{core => coretests}/tests/hash/sip.rs (100%) rename library/{core => coretests}/tests/intrinsics.rs (100%) rename library/{core => coretests}/tests/io/borrowed_buf.rs (100%) rename library/{core => coretests}/tests/io/mod.rs (100%) rename library/{core => coretests}/tests/iter/adapters/array_chunks.rs (100%) rename library/{core => coretests}/tests/iter/adapters/by_ref_sized.rs (100%) rename library/{core => coretests}/tests/iter/adapters/chain.rs (100%) rename library/{core => coretests}/tests/iter/adapters/cloned.rs (100%) rename library/{core => coretests}/tests/iter/adapters/copied.rs (100%) rename library/{core => coretests}/tests/iter/adapters/cycle.rs (100%) rename library/{core => coretests}/tests/iter/adapters/enumerate.rs (100%) rename library/{core => coretests}/tests/iter/adapters/filter.rs (100%) rename library/{core => coretests}/tests/iter/adapters/filter_map.rs (100%) rename library/{core => coretests}/tests/iter/adapters/flat_map.rs (100%) rename library/{core => coretests}/tests/iter/adapters/flatten.rs (100%) rename library/{core => coretests}/tests/iter/adapters/fuse.rs (100%) rename library/{core => coretests}/tests/iter/adapters/inspect.rs (100%) rename library/{core => coretests}/tests/iter/adapters/intersperse.rs (100%) rename library/{core => coretests}/tests/iter/adapters/map.rs (100%) rename library/{core => coretests}/tests/iter/adapters/map_windows.rs (100%) rename library/{core => coretests}/tests/iter/adapters/mod.rs (100%) rename library/{core => coretests}/tests/iter/adapters/peekable.rs (100%) rename library/{core => coretests}/tests/iter/adapters/scan.rs (100%) rename library/{core => coretests}/tests/iter/adapters/skip.rs (100%) rename library/{core => coretests}/tests/iter/adapters/skip_while.rs (100%) rename library/{core => coretests}/tests/iter/adapters/step_by.rs (100%) rename library/{core => coretests}/tests/iter/adapters/take.rs (100%) rename library/{core => coretests}/tests/iter/adapters/take_while.rs (100%) rename library/{core => coretests}/tests/iter/adapters/zip.rs (100%) rename library/{core => coretests}/tests/iter/mod.rs (100%) rename library/{core => coretests}/tests/iter/range.rs (100%) rename library/{core => coretests}/tests/iter/sources.rs (100%) rename library/{core => coretests}/tests/iter/traits/accum.rs (100%) rename library/{core => coretests}/tests/iter/traits/double_ended.rs (100%) rename library/{core => coretests}/tests/iter/traits/iterator.rs (100%) rename library/{core => coretests}/tests/iter/traits/mod.rs (100%) rename library/{core => coretests}/tests/iter/traits/step.rs (100%) rename library/{core => coretests}/tests/lazy.rs (100%) rename library/{core => coretests}/tests/lib.rs (100%) rename library/{core => coretests}/tests/macros.rs (100%) rename library/{core => coretests}/tests/macros_bootstrap.rs (100%) rename library/{core => coretests}/tests/manually_drop.rs (100%) rename library/{core => coretests}/tests/mem.rs (100%) rename library/{core => coretests}/tests/net/ip_addr.rs (100%) rename library/{core => coretests}/tests/net/mod.rs (100%) rename library/{core => coretests}/tests/net/parser.rs (100%) rename library/{core => coretests}/tests/net/socket_addr.rs (100%) rename library/{core => coretests}/tests/nonzero.rs (100%) rename library/{core => coretests}/tests/num/bignum.rs (100%) rename library/{core => coretests}/tests/num/const_from.rs (100%) rename library/{core => coretests}/tests/num/dec2flt/float.rs (100%) rename library/{core => coretests}/tests/num/dec2flt/lemire.rs (100%) rename library/{core => coretests}/tests/num/dec2flt/mod.rs (100%) rename library/{core => coretests}/tests/num/dec2flt/parse.rs (100%) rename library/{core => coretests}/tests/num/float_iter_sum_identity.rs (100%) rename library/{core => coretests}/tests/num/flt2dec/estimator.rs (100%) rename library/{core => coretests}/tests/num/flt2dec/mod.rs (100%) rename library/{core => coretests}/tests/num/flt2dec/random.rs (100%) rename library/{core => coretests}/tests/num/flt2dec/strategy/dragon.rs (100%) rename library/{core => coretests}/tests/num/flt2dec/strategy/grisu.rs (100%) rename library/{core => coretests}/tests/num/i128.rs (100%) rename library/{core => coretests}/tests/num/i16.rs (100%) rename library/{core => coretests}/tests/num/i32.rs (100%) rename library/{core => coretests}/tests/num/i64.rs (100%) rename library/{core => coretests}/tests/num/i8.rs (100%) rename library/{core => coretests}/tests/num/ieee754.rs (100%) rename library/{core => coretests}/tests/num/int_log.rs (100%) rename library/{core => coretests}/tests/num/int_macros.rs (100%) rename library/{core => coretests}/tests/num/int_sqrt.rs (100%) rename library/{core => coretests}/tests/num/midpoint.rs (100%) rename library/{core => coretests}/tests/num/mod.rs (100%) rename library/{core => coretests}/tests/num/nan.rs (100%) rename library/{core => coretests}/tests/num/ops.rs (100%) rename library/{core => coretests}/tests/num/u128.rs (100%) rename library/{core => coretests}/tests/num/u16.rs (100%) rename library/{core => coretests}/tests/num/u32.rs (100%) rename library/{core => coretests}/tests/num/u64.rs (100%) rename library/{core => coretests}/tests/num/u8.rs (100%) rename library/{core => coretests}/tests/num/uint_macros.rs (100%) rename library/{core => coretests}/tests/num/wrapping.rs (100%) rename library/{core => coretests}/tests/ops.rs (100%) rename library/{core => coretests}/tests/ops/control_flow.rs (100%) rename library/{core => coretests}/tests/ops/from_residual.rs (100%) rename library/{core => coretests}/tests/option.rs (100%) rename library/{core => coretests}/tests/panic.rs (100%) rename library/{core => coretests}/tests/panic/location.rs (100%) rename library/{core => coretests}/tests/pattern.rs (100%) rename library/{core => coretests}/tests/pin.rs (100%) rename library/{core => coretests}/tests/pin_macro.rs (100%) rename library/{core => coretests}/tests/ptr.rs (100%) rename library/{core => coretests}/tests/result.rs (100%) rename library/{core => coretests}/tests/simd.rs (100%) rename library/{core => coretests}/tests/slice.rs (100%) rename library/{core => coretests}/tests/str.rs (100%) rename library/{core => coretests}/tests/str_lossy.rs (100%) rename library/{core => coretests}/tests/task.rs (100%) rename library/{core => coretests}/tests/time.rs (100%) rename library/{core => coretests}/tests/tuple.rs (100%) rename library/{core => coretests}/tests/unicode.rs (100%) rename library/{core => coretests}/tests/waker.rs (100%) diff --git a/library/Cargo.lock b/library/Cargo.lock index 7b9081d46a05..30875482dc06 100644 --- a/library/Cargo.lock +++ b/library/Cargo.lock @@ -72,6 +72,10 @@ dependencies = [ [[package]] name = "core" version = "0.0.0" + +[[package]] +name = "coretests" +version = "0.0.0" dependencies = [ "rand", "rand_xorshift", diff --git a/library/Cargo.toml b/library/Cargo.toml index e59aa518804f..1205f7c9ed6b 100644 --- a/library/Cargo.toml +++ b/library/Cargo.toml @@ -3,6 +3,7 @@ resolver = "1" members = [ "std", "sysroot", + "coretests", ] exclude = [ diff --git a/library/core/Cargo.toml b/library/core/Cargo.toml index 46c55c437cce..b7c6db6c78dd 100644 --- a/library/core/Cargo.toml +++ b/library/core/Cargo.toml @@ -15,19 +15,6 @@ edition = "2021" test = false bench = false -[[test]] -name = "coretests" -path = "tests/lib.rs" - -[[bench]] -name = "corebenches" -path = "benches/lib.rs" -test = true - -[dev-dependencies] -rand = { version = "0.8.5", default-features = false } -rand_xorshift = { version = "0.3.0", default-features = false } - [features] # Make panics and failed asserts immediately abort without formatting any message panic_immediate_abort = [] diff --git a/library/coretests/Cargo.toml b/library/coretests/Cargo.toml new file mode 100644 index 000000000000..ec940abea117 --- /dev/null +++ b/library/coretests/Cargo.toml @@ -0,0 +1,27 @@ +[package] +name = "coretests" +version = "0.0.0" +license = "MIT OR Apache-2.0" +repository = "https://github.com/rust-lang/rust.git" +description = "Tests for the Rust Core Library" +autotests = false +autobenches = false +edition = "2021" + +[lib] +path = "lib.rs" +test = false +bench = false + +[[test]] +name = "coretests" +path = "tests/lib.rs" + +[[bench]] +name = "corebenches" +path = "benches/lib.rs" +test = true + +[dev-dependencies] +rand = { version = "0.8.5", default-features = false } +rand_xorshift = { version = "0.3.0", default-features = false } diff --git a/library/core/benches/any.rs b/library/coretests/benches/any.rs similarity index 100% rename from library/core/benches/any.rs rename to library/coretests/benches/any.rs diff --git a/library/core/benches/array.rs b/library/coretests/benches/array.rs similarity index 100% rename from library/core/benches/array.rs rename to library/coretests/benches/array.rs diff --git a/library/core/benches/ascii.rs b/library/coretests/benches/ascii.rs similarity index 100% rename from library/core/benches/ascii.rs rename to library/coretests/benches/ascii.rs diff --git a/library/core/benches/ascii/is_ascii.rs b/library/coretests/benches/ascii/is_ascii.rs similarity index 100% rename from library/core/benches/ascii/is_ascii.rs rename to library/coretests/benches/ascii/is_ascii.rs diff --git a/library/core/benches/char/methods.rs b/library/coretests/benches/char/methods.rs similarity index 100% rename from library/core/benches/char/methods.rs rename to library/coretests/benches/char/methods.rs diff --git a/library/core/benches/char/mod.rs b/library/coretests/benches/char/mod.rs similarity index 100% rename from library/core/benches/char/mod.rs rename to library/coretests/benches/char/mod.rs diff --git a/library/core/benches/fmt.rs b/library/coretests/benches/fmt.rs similarity index 100% rename from library/core/benches/fmt.rs rename to library/coretests/benches/fmt.rs diff --git a/library/core/benches/hash/mod.rs b/library/coretests/benches/hash/mod.rs similarity index 100% rename from library/core/benches/hash/mod.rs rename to library/coretests/benches/hash/mod.rs diff --git a/library/core/benches/hash/sip.rs b/library/coretests/benches/hash/sip.rs similarity index 100% rename from library/core/benches/hash/sip.rs rename to library/coretests/benches/hash/sip.rs diff --git a/library/core/benches/iter.rs b/library/coretests/benches/iter.rs similarity index 100% rename from library/core/benches/iter.rs rename to library/coretests/benches/iter.rs diff --git a/library/core/benches/lib.rs b/library/coretests/benches/lib.rs similarity index 100% rename from library/core/benches/lib.rs rename to library/coretests/benches/lib.rs diff --git a/library/core/benches/net/addr_parser.rs b/library/coretests/benches/net/addr_parser.rs similarity index 100% rename from library/core/benches/net/addr_parser.rs rename to library/coretests/benches/net/addr_parser.rs diff --git a/library/core/benches/net/mod.rs b/library/coretests/benches/net/mod.rs similarity index 100% rename from library/core/benches/net/mod.rs rename to library/coretests/benches/net/mod.rs diff --git a/library/core/benches/num/dec2flt/mod.rs b/library/coretests/benches/num/dec2flt/mod.rs similarity index 100% rename from library/core/benches/num/dec2flt/mod.rs rename to library/coretests/benches/num/dec2flt/mod.rs diff --git a/library/core/benches/num/flt2dec/mod.rs b/library/coretests/benches/num/flt2dec/mod.rs similarity index 100% rename from library/core/benches/num/flt2dec/mod.rs rename to library/coretests/benches/num/flt2dec/mod.rs diff --git a/library/core/benches/num/flt2dec/strategy/dragon.rs b/library/coretests/benches/num/flt2dec/strategy/dragon.rs similarity index 100% rename from library/core/benches/num/flt2dec/strategy/dragon.rs rename to library/coretests/benches/num/flt2dec/strategy/dragon.rs diff --git a/library/core/benches/num/flt2dec/strategy/grisu.rs b/library/coretests/benches/num/flt2dec/strategy/grisu.rs similarity index 100% rename from library/core/benches/num/flt2dec/strategy/grisu.rs rename to library/coretests/benches/num/flt2dec/strategy/grisu.rs diff --git a/library/core/benches/num/int_log/mod.rs b/library/coretests/benches/num/int_log/mod.rs similarity index 100% rename from library/core/benches/num/int_log/mod.rs rename to library/coretests/benches/num/int_log/mod.rs diff --git a/library/core/benches/num/int_pow/mod.rs b/library/coretests/benches/num/int_pow/mod.rs similarity index 100% rename from library/core/benches/num/int_pow/mod.rs rename to library/coretests/benches/num/int_pow/mod.rs diff --git a/library/core/benches/num/int_sqrt/mod.rs b/library/coretests/benches/num/int_sqrt/mod.rs similarity index 100% rename from library/core/benches/num/int_sqrt/mod.rs rename to library/coretests/benches/num/int_sqrt/mod.rs diff --git a/library/core/benches/num/mod.rs b/library/coretests/benches/num/mod.rs similarity index 100% rename from library/core/benches/num/mod.rs rename to library/coretests/benches/num/mod.rs diff --git a/library/core/benches/ops.rs b/library/coretests/benches/ops.rs similarity index 100% rename from library/core/benches/ops.rs rename to library/coretests/benches/ops.rs diff --git a/library/core/benches/pattern.rs b/library/coretests/benches/pattern.rs similarity index 100% rename from library/core/benches/pattern.rs rename to library/coretests/benches/pattern.rs diff --git a/library/core/benches/slice.rs b/library/coretests/benches/slice.rs similarity index 100% rename from library/core/benches/slice.rs rename to library/coretests/benches/slice.rs diff --git a/library/core/benches/str.rs b/library/coretests/benches/str.rs similarity index 100% rename from library/core/benches/str.rs rename to library/coretests/benches/str.rs diff --git a/library/core/benches/str/char_count.rs b/library/coretests/benches/str/char_count.rs similarity index 100% rename from library/core/benches/str/char_count.rs rename to library/coretests/benches/str/char_count.rs diff --git a/library/core/benches/str/corpora.rs b/library/coretests/benches/str/corpora.rs similarity index 100% rename from library/core/benches/str/corpora.rs rename to library/coretests/benches/str/corpora.rs diff --git a/library/core/benches/str/debug.rs b/library/coretests/benches/str/debug.rs similarity index 100% rename from library/core/benches/str/debug.rs rename to library/coretests/benches/str/debug.rs diff --git a/library/core/benches/str/iter.rs b/library/coretests/benches/str/iter.rs similarity index 100% rename from library/core/benches/str/iter.rs rename to library/coretests/benches/str/iter.rs diff --git a/library/core/benches/tuple.rs b/library/coretests/benches/tuple.rs similarity index 100% rename from library/core/benches/tuple.rs rename to library/coretests/benches/tuple.rs diff --git a/library/coretests/lib.rs b/library/coretests/lib.rs new file mode 100644 index 000000000000..b49208cd4eb3 --- /dev/null +++ b/library/coretests/lib.rs @@ -0,0 +1 @@ +// Intentionally left empty. diff --git a/library/core/tests/alloc.rs b/library/coretests/tests/alloc.rs similarity index 100% rename from library/core/tests/alloc.rs rename to library/coretests/tests/alloc.rs diff --git a/library/core/tests/any.rs b/library/coretests/tests/any.rs similarity index 100% rename from library/core/tests/any.rs rename to library/coretests/tests/any.rs diff --git a/library/core/tests/array.rs b/library/coretests/tests/array.rs similarity index 100% rename from library/core/tests/array.rs rename to library/coretests/tests/array.rs diff --git a/library/core/tests/ascii.rs b/library/coretests/tests/ascii.rs similarity index 100% rename from library/core/tests/ascii.rs rename to library/coretests/tests/ascii.rs diff --git a/library/core/tests/ascii_char.rs b/library/coretests/tests/ascii_char.rs similarity index 100% rename from library/core/tests/ascii_char.rs rename to library/coretests/tests/ascii_char.rs diff --git a/library/core/tests/asserting.rs b/library/coretests/tests/asserting.rs similarity index 100% rename from library/core/tests/asserting.rs rename to library/coretests/tests/asserting.rs diff --git a/library/core/tests/async_iter/mod.rs b/library/coretests/tests/async_iter/mod.rs similarity index 100% rename from library/core/tests/async_iter/mod.rs rename to library/coretests/tests/async_iter/mod.rs diff --git a/library/core/tests/atomic.rs b/library/coretests/tests/atomic.rs similarity index 100% rename from library/core/tests/atomic.rs rename to library/coretests/tests/atomic.rs diff --git a/library/core/tests/bool.rs b/library/coretests/tests/bool.rs similarity index 100% rename from library/core/tests/bool.rs rename to library/coretests/tests/bool.rs diff --git a/library/core/tests/bstr.rs b/library/coretests/tests/bstr.rs similarity index 100% rename from library/core/tests/bstr.rs rename to library/coretests/tests/bstr.rs diff --git a/library/core/tests/cell.rs b/library/coretests/tests/cell.rs similarity index 100% rename from library/core/tests/cell.rs rename to library/coretests/tests/cell.rs diff --git a/library/core/tests/char.rs b/library/coretests/tests/char.rs similarity index 100% rename from library/core/tests/char.rs rename to library/coretests/tests/char.rs diff --git a/library/core/tests/clone.rs b/library/coretests/tests/clone.rs similarity index 100% rename from library/core/tests/clone.rs rename to library/coretests/tests/clone.rs diff --git a/library/core/tests/cmp.rs b/library/coretests/tests/cmp.rs similarity index 100% rename from library/core/tests/cmp.rs rename to library/coretests/tests/cmp.rs diff --git a/library/core/tests/const_ptr.rs b/library/coretests/tests/const_ptr.rs similarity index 100% rename from library/core/tests/const_ptr.rs rename to library/coretests/tests/const_ptr.rs diff --git a/library/core/tests/convert.rs b/library/coretests/tests/convert.rs similarity index 100% rename from library/core/tests/convert.rs rename to library/coretests/tests/convert.rs diff --git a/library/core/tests/error.rs b/library/coretests/tests/error.rs similarity index 100% rename from library/core/tests/error.rs rename to library/coretests/tests/error.rs diff --git a/library/core/tests/ffi.rs b/library/coretests/tests/ffi.rs similarity index 100% rename from library/core/tests/ffi.rs rename to library/coretests/tests/ffi.rs diff --git a/library/core/tests/ffi/cstr.rs b/library/coretests/tests/ffi/cstr.rs similarity index 100% rename from library/core/tests/ffi/cstr.rs rename to library/coretests/tests/ffi/cstr.rs diff --git a/library/core/tests/fmt/builders.rs b/library/coretests/tests/fmt/builders.rs similarity index 100% rename from library/core/tests/fmt/builders.rs rename to library/coretests/tests/fmt/builders.rs diff --git a/library/core/tests/fmt/float.rs b/library/coretests/tests/fmt/float.rs similarity index 100% rename from library/core/tests/fmt/float.rs rename to library/coretests/tests/fmt/float.rs diff --git a/library/core/tests/fmt/mod.rs b/library/coretests/tests/fmt/mod.rs similarity index 100% rename from library/core/tests/fmt/mod.rs rename to library/coretests/tests/fmt/mod.rs diff --git a/library/core/tests/fmt/num.rs b/library/coretests/tests/fmt/num.rs similarity index 100% rename from library/core/tests/fmt/num.rs rename to library/coretests/tests/fmt/num.rs diff --git a/library/core/tests/future.rs b/library/coretests/tests/future.rs similarity index 100% rename from library/core/tests/future.rs rename to library/coretests/tests/future.rs diff --git a/library/core/tests/hash/mod.rs b/library/coretests/tests/hash/mod.rs similarity index 100% rename from library/core/tests/hash/mod.rs rename to library/coretests/tests/hash/mod.rs diff --git a/library/core/tests/hash/sip.rs b/library/coretests/tests/hash/sip.rs similarity index 100% rename from library/core/tests/hash/sip.rs rename to library/coretests/tests/hash/sip.rs diff --git a/library/core/tests/intrinsics.rs b/library/coretests/tests/intrinsics.rs similarity index 100% rename from library/core/tests/intrinsics.rs rename to library/coretests/tests/intrinsics.rs diff --git a/library/core/tests/io/borrowed_buf.rs b/library/coretests/tests/io/borrowed_buf.rs similarity index 100% rename from library/core/tests/io/borrowed_buf.rs rename to library/coretests/tests/io/borrowed_buf.rs diff --git a/library/core/tests/io/mod.rs b/library/coretests/tests/io/mod.rs similarity index 100% rename from library/core/tests/io/mod.rs rename to library/coretests/tests/io/mod.rs diff --git a/library/core/tests/iter/adapters/array_chunks.rs b/library/coretests/tests/iter/adapters/array_chunks.rs similarity index 100% rename from library/core/tests/iter/adapters/array_chunks.rs rename to library/coretests/tests/iter/adapters/array_chunks.rs diff --git a/library/core/tests/iter/adapters/by_ref_sized.rs b/library/coretests/tests/iter/adapters/by_ref_sized.rs similarity index 100% rename from library/core/tests/iter/adapters/by_ref_sized.rs rename to library/coretests/tests/iter/adapters/by_ref_sized.rs diff --git a/library/core/tests/iter/adapters/chain.rs b/library/coretests/tests/iter/adapters/chain.rs similarity index 100% rename from library/core/tests/iter/adapters/chain.rs rename to library/coretests/tests/iter/adapters/chain.rs diff --git a/library/core/tests/iter/adapters/cloned.rs b/library/coretests/tests/iter/adapters/cloned.rs similarity index 100% rename from library/core/tests/iter/adapters/cloned.rs rename to library/coretests/tests/iter/adapters/cloned.rs diff --git a/library/core/tests/iter/adapters/copied.rs b/library/coretests/tests/iter/adapters/copied.rs similarity index 100% rename from library/core/tests/iter/adapters/copied.rs rename to library/coretests/tests/iter/adapters/copied.rs diff --git a/library/core/tests/iter/adapters/cycle.rs b/library/coretests/tests/iter/adapters/cycle.rs similarity index 100% rename from library/core/tests/iter/adapters/cycle.rs rename to library/coretests/tests/iter/adapters/cycle.rs diff --git a/library/core/tests/iter/adapters/enumerate.rs b/library/coretests/tests/iter/adapters/enumerate.rs similarity index 100% rename from library/core/tests/iter/adapters/enumerate.rs rename to library/coretests/tests/iter/adapters/enumerate.rs diff --git a/library/core/tests/iter/adapters/filter.rs b/library/coretests/tests/iter/adapters/filter.rs similarity index 100% rename from library/core/tests/iter/adapters/filter.rs rename to library/coretests/tests/iter/adapters/filter.rs diff --git a/library/core/tests/iter/adapters/filter_map.rs b/library/coretests/tests/iter/adapters/filter_map.rs similarity index 100% rename from library/core/tests/iter/adapters/filter_map.rs rename to library/coretests/tests/iter/adapters/filter_map.rs diff --git a/library/core/tests/iter/adapters/flat_map.rs b/library/coretests/tests/iter/adapters/flat_map.rs similarity index 100% rename from library/core/tests/iter/adapters/flat_map.rs rename to library/coretests/tests/iter/adapters/flat_map.rs diff --git a/library/core/tests/iter/adapters/flatten.rs b/library/coretests/tests/iter/adapters/flatten.rs similarity index 100% rename from library/core/tests/iter/adapters/flatten.rs rename to library/coretests/tests/iter/adapters/flatten.rs diff --git a/library/core/tests/iter/adapters/fuse.rs b/library/coretests/tests/iter/adapters/fuse.rs similarity index 100% rename from library/core/tests/iter/adapters/fuse.rs rename to library/coretests/tests/iter/adapters/fuse.rs diff --git a/library/core/tests/iter/adapters/inspect.rs b/library/coretests/tests/iter/adapters/inspect.rs similarity index 100% rename from library/core/tests/iter/adapters/inspect.rs rename to library/coretests/tests/iter/adapters/inspect.rs diff --git a/library/core/tests/iter/adapters/intersperse.rs b/library/coretests/tests/iter/adapters/intersperse.rs similarity index 100% rename from library/core/tests/iter/adapters/intersperse.rs rename to library/coretests/tests/iter/adapters/intersperse.rs diff --git a/library/core/tests/iter/adapters/map.rs b/library/coretests/tests/iter/adapters/map.rs similarity index 100% rename from library/core/tests/iter/adapters/map.rs rename to library/coretests/tests/iter/adapters/map.rs diff --git a/library/core/tests/iter/adapters/map_windows.rs b/library/coretests/tests/iter/adapters/map_windows.rs similarity index 100% rename from library/core/tests/iter/adapters/map_windows.rs rename to library/coretests/tests/iter/adapters/map_windows.rs diff --git a/library/core/tests/iter/adapters/mod.rs b/library/coretests/tests/iter/adapters/mod.rs similarity index 100% rename from library/core/tests/iter/adapters/mod.rs rename to library/coretests/tests/iter/adapters/mod.rs diff --git a/library/core/tests/iter/adapters/peekable.rs b/library/coretests/tests/iter/adapters/peekable.rs similarity index 100% rename from library/core/tests/iter/adapters/peekable.rs rename to library/coretests/tests/iter/adapters/peekable.rs diff --git a/library/core/tests/iter/adapters/scan.rs b/library/coretests/tests/iter/adapters/scan.rs similarity index 100% rename from library/core/tests/iter/adapters/scan.rs rename to library/coretests/tests/iter/adapters/scan.rs diff --git a/library/core/tests/iter/adapters/skip.rs b/library/coretests/tests/iter/adapters/skip.rs similarity index 100% rename from library/core/tests/iter/adapters/skip.rs rename to library/coretests/tests/iter/adapters/skip.rs diff --git a/library/core/tests/iter/adapters/skip_while.rs b/library/coretests/tests/iter/adapters/skip_while.rs similarity index 100% rename from library/core/tests/iter/adapters/skip_while.rs rename to library/coretests/tests/iter/adapters/skip_while.rs diff --git a/library/core/tests/iter/adapters/step_by.rs b/library/coretests/tests/iter/adapters/step_by.rs similarity index 100% rename from library/core/tests/iter/adapters/step_by.rs rename to library/coretests/tests/iter/adapters/step_by.rs diff --git a/library/core/tests/iter/adapters/take.rs b/library/coretests/tests/iter/adapters/take.rs similarity index 100% rename from library/core/tests/iter/adapters/take.rs rename to library/coretests/tests/iter/adapters/take.rs diff --git a/library/core/tests/iter/adapters/take_while.rs b/library/coretests/tests/iter/adapters/take_while.rs similarity index 100% rename from library/core/tests/iter/adapters/take_while.rs rename to library/coretests/tests/iter/adapters/take_while.rs diff --git a/library/core/tests/iter/adapters/zip.rs b/library/coretests/tests/iter/adapters/zip.rs similarity index 100% rename from library/core/tests/iter/adapters/zip.rs rename to library/coretests/tests/iter/adapters/zip.rs diff --git a/library/core/tests/iter/mod.rs b/library/coretests/tests/iter/mod.rs similarity index 100% rename from library/core/tests/iter/mod.rs rename to library/coretests/tests/iter/mod.rs diff --git a/library/core/tests/iter/range.rs b/library/coretests/tests/iter/range.rs similarity index 100% rename from library/core/tests/iter/range.rs rename to library/coretests/tests/iter/range.rs diff --git a/library/core/tests/iter/sources.rs b/library/coretests/tests/iter/sources.rs similarity index 100% rename from library/core/tests/iter/sources.rs rename to library/coretests/tests/iter/sources.rs diff --git a/library/core/tests/iter/traits/accum.rs b/library/coretests/tests/iter/traits/accum.rs similarity index 100% rename from library/core/tests/iter/traits/accum.rs rename to library/coretests/tests/iter/traits/accum.rs diff --git a/library/core/tests/iter/traits/double_ended.rs b/library/coretests/tests/iter/traits/double_ended.rs similarity index 100% rename from library/core/tests/iter/traits/double_ended.rs rename to library/coretests/tests/iter/traits/double_ended.rs diff --git a/library/core/tests/iter/traits/iterator.rs b/library/coretests/tests/iter/traits/iterator.rs similarity index 100% rename from library/core/tests/iter/traits/iterator.rs rename to library/coretests/tests/iter/traits/iterator.rs diff --git a/library/core/tests/iter/traits/mod.rs b/library/coretests/tests/iter/traits/mod.rs similarity index 100% rename from library/core/tests/iter/traits/mod.rs rename to library/coretests/tests/iter/traits/mod.rs diff --git a/library/core/tests/iter/traits/step.rs b/library/coretests/tests/iter/traits/step.rs similarity index 100% rename from library/core/tests/iter/traits/step.rs rename to library/coretests/tests/iter/traits/step.rs diff --git a/library/core/tests/lazy.rs b/library/coretests/tests/lazy.rs similarity index 100% rename from library/core/tests/lazy.rs rename to library/coretests/tests/lazy.rs diff --git a/library/core/tests/lib.rs b/library/coretests/tests/lib.rs similarity index 100% rename from library/core/tests/lib.rs rename to library/coretests/tests/lib.rs diff --git a/library/core/tests/macros.rs b/library/coretests/tests/macros.rs similarity index 100% rename from library/core/tests/macros.rs rename to library/coretests/tests/macros.rs diff --git a/library/core/tests/macros_bootstrap.rs b/library/coretests/tests/macros_bootstrap.rs similarity index 100% rename from library/core/tests/macros_bootstrap.rs rename to library/coretests/tests/macros_bootstrap.rs diff --git a/library/core/tests/manually_drop.rs b/library/coretests/tests/manually_drop.rs similarity index 100% rename from library/core/tests/manually_drop.rs rename to library/coretests/tests/manually_drop.rs diff --git a/library/core/tests/mem.rs b/library/coretests/tests/mem.rs similarity index 100% rename from library/core/tests/mem.rs rename to library/coretests/tests/mem.rs diff --git a/library/core/tests/net/ip_addr.rs b/library/coretests/tests/net/ip_addr.rs similarity index 100% rename from library/core/tests/net/ip_addr.rs rename to library/coretests/tests/net/ip_addr.rs diff --git a/library/core/tests/net/mod.rs b/library/coretests/tests/net/mod.rs similarity index 100% rename from library/core/tests/net/mod.rs rename to library/coretests/tests/net/mod.rs diff --git a/library/core/tests/net/parser.rs b/library/coretests/tests/net/parser.rs similarity index 100% rename from library/core/tests/net/parser.rs rename to library/coretests/tests/net/parser.rs diff --git a/library/core/tests/net/socket_addr.rs b/library/coretests/tests/net/socket_addr.rs similarity index 100% rename from library/core/tests/net/socket_addr.rs rename to library/coretests/tests/net/socket_addr.rs diff --git a/library/core/tests/nonzero.rs b/library/coretests/tests/nonzero.rs similarity index 100% rename from library/core/tests/nonzero.rs rename to library/coretests/tests/nonzero.rs diff --git a/library/core/tests/num/bignum.rs b/library/coretests/tests/num/bignum.rs similarity index 100% rename from library/core/tests/num/bignum.rs rename to library/coretests/tests/num/bignum.rs diff --git a/library/core/tests/num/const_from.rs b/library/coretests/tests/num/const_from.rs similarity index 100% rename from library/core/tests/num/const_from.rs rename to library/coretests/tests/num/const_from.rs diff --git a/library/core/tests/num/dec2flt/float.rs b/library/coretests/tests/num/dec2flt/float.rs similarity index 100% rename from library/core/tests/num/dec2flt/float.rs rename to library/coretests/tests/num/dec2flt/float.rs diff --git a/library/core/tests/num/dec2flt/lemire.rs b/library/coretests/tests/num/dec2flt/lemire.rs similarity index 100% rename from library/core/tests/num/dec2flt/lemire.rs rename to library/coretests/tests/num/dec2flt/lemire.rs diff --git a/library/core/tests/num/dec2flt/mod.rs b/library/coretests/tests/num/dec2flt/mod.rs similarity index 100% rename from library/core/tests/num/dec2flt/mod.rs rename to library/coretests/tests/num/dec2flt/mod.rs diff --git a/library/core/tests/num/dec2flt/parse.rs b/library/coretests/tests/num/dec2flt/parse.rs similarity index 100% rename from library/core/tests/num/dec2flt/parse.rs rename to library/coretests/tests/num/dec2flt/parse.rs diff --git a/library/core/tests/num/float_iter_sum_identity.rs b/library/coretests/tests/num/float_iter_sum_identity.rs similarity index 100% rename from library/core/tests/num/float_iter_sum_identity.rs rename to library/coretests/tests/num/float_iter_sum_identity.rs diff --git a/library/core/tests/num/flt2dec/estimator.rs b/library/coretests/tests/num/flt2dec/estimator.rs similarity index 100% rename from library/core/tests/num/flt2dec/estimator.rs rename to library/coretests/tests/num/flt2dec/estimator.rs diff --git a/library/core/tests/num/flt2dec/mod.rs b/library/coretests/tests/num/flt2dec/mod.rs similarity index 100% rename from library/core/tests/num/flt2dec/mod.rs rename to library/coretests/tests/num/flt2dec/mod.rs diff --git a/library/core/tests/num/flt2dec/random.rs b/library/coretests/tests/num/flt2dec/random.rs similarity index 100% rename from library/core/tests/num/flt2dec/random.rs rename to library/coretests/tests/num/flt2dec/random.rs diff --git a/library/core/tests/num/flt2dec/strategy/dragon.rs b/library/coretests/tests/num/flt2dec/strategy/dragon.rs similarity index 100% rename from library/core/tests/num/flt2dec/strategy/dragon.rs rename to library/coretests/tests/num/flt2dec/strategy/dragon.rs diff --git a/library/core/tests/num/flt2dec/strategy/grisu.rs b/library/coretests/tests/num/flt2dec/strategy/grisu.rs similarity index 100% rename from library/core/tests/num/flt2dec/strategy/grisu.rs rename to library/coretests/tests/num/flt2dec/strategy/grisu.rs diff --git a/library/core/tests/num/i128.rs b/library/coretests/tests/num/i128.rs similarity index 100% rename from library/core/tests/num/i128.rs rename to library/coretests/tests/num/i128.rs diff --git a/library/core/tests/num/i16.rs b/library/coretests/tests/num/i16.rs similarity index 100% rename from library/core/tests/num/i16.rs rename to library/coretests/tests/num/i16.rs diff --git a/library/core/tests/num/i32.rs b/library/coretests/tests/num/i32.rs similarity index 100% rename from library/core/tests/num/i32.rs rename to library/coretests/tests/num/i32.rs diff --git a/library/core/tests/num/i64.rs b/library/coretests/tests/num/i64.rs similarity index 100% rename from library/core/tests/num/i64.rs rename to library/coretests/tests/num/i64.rs diff --git a/library/core/tests/num/i8.rs b/library/coretests/tests/num/i8.rs similarity index 100% rename from library/core/tests/num/i8.rs rename to library/coretests/tests/num/i8.rs diff --git a/library/core/tests/num/ieee754.rs b/library/coretests/tests/num/ieee754.rs similarity index 100% rename from library/core/tests/num/ieee754.rs rename to library/coretests/tests/num/ieee754.rs diff --git a/library/core/tests/num/int_log.rs b/library/coretests/tests/num/int_log.rs similarity index 100% rename from library/core/tests/num/int_log.rs rename to library/coretests/tests/num/int_log.rs diff --git a/library/core/tests/num/int_macros.rs b/library/coretests/tests/num/int_macros.rs similarity index 100% rename from library/core/tests/num/int_macros.rs rename to library/coretests/tests/num/int_macros.rs diff --git a/library/core/tests/num/int_sqrt.rs b/library/coretests/tests/num/int_sqrt.rs similarity index 100% rename from library/core/tests/num/int_sqrt.rs rename to library/coretests/tests/num/int_sqrt.rs diff --git a/library/core/tests/num/midpoint.rs b/library/coretests/tests/num/midpoint.rs similarity index 100% rename from library/core/tests/num/midpoint.rs rename to library/coretests/tests/num/midpoint.rs diff --git a/library/core/tests/num/mod.rs b/library/coretests/tests/num/mod.rs similarity index 100% rename from library/core/tests/num/mod.rs rename to library/coretests/tests/num/mod.rs diff --git a/library/core/tests/num/nan.rs b/library/coretests/tests/num/nan.rs similarity index 100% rename from library/core/tests/num/nan.rs rename to library/coretests/tests/num/nan.rs diff --git a/library/core/tests/num/ops.rs b/library/coretests/tests/num/ops.rs similarity index 100% rename from library/core/tests/num/ops.rs rename to library/coretests/tests/num/ops.rs diff --git a/library/core/tests/num/u128.rs b/library/coretests/tests/num/u128.rs similarity index 100% rename from library/core/tests/num/u128.rs rename to library/coretests/tests/num/u128.rs diff --git a/library/core/tests/num/u16.rs b/library/coretests/tests/num/u16.rs similarity index 100% rename from library/core/tests/num/u16.rs rename to library/coretests/tests/num/u16.rs diff --git a/library/core/tests/num/u32.rs b/library/coretests/tests/num/u32.rs similarity index 100% rename from library/core/tests/num/u32.rs rename to library/coretests/tests/num/u32.rs diff --git a/library/core/tests/num/u64.rs b/library/coretests/tests/num/u64.rs similarity index 100% rename from library/core/tests/num/u64.rs rename to library/coretests/tests/num/u64.rs diff --git a/library/core/tests/num/u8.rs b/library/coretests/tests/num/u8.rs similarity index 100% rename from library/core/tests/num/u8.rs rename to library/coretests/tests/num/u8.rs diff --git a/library/core/tests/num/uint_macros.rs b/library/coretests/tests/num/uint_macros.rs similarity index 100% rename from library/core/tests/num/uint_macros.rs rename to library/coretests/tests/num/uint_macros.rs diff --git a/library/core/tests/num/wrapping.rs b/library/coretests/tests/num/wrapping.rs similarity index 100% rename from library/core/tests/num/wrapping.rs rename to library/coretests/tests/num/wrapping.rs diff --git a/library/core/tests/ops.rs b/library/coretests/tests/ops.rs similarity index 100% rename from library/core/tests/ops.rs rename to library/coretests/tests/ops.rs diff --git a/library/core/tests/ops/control_flow.rs b/library/coretests/tests/ops/control_flow.rs similarity index 100% rename from library/core/tests/ops/control_flow.rs rename to library/coretests/tests/ops/control_flow.rs diff --git a/library/core/tests/ops/from_residual.rs b/library/coretests/tests/ops/from_residual.rs similarity index 100% rename from library/core/tests/ops/from_residual.rs rename to library/coretests/tests/ops/from_residual.rs diff --git a/library/core/tests/option.rs b/library/coretests/tests/option.rs similarity index 100% rename from library/core/tests/option.rs rename to library/coretests/tests/option.rs diff --git a/library/core/tests/panic.rs b/library/coretests/tests/panic.rs similarity index 100% rename from library/core/tests/panic.rs rename to library/coretests/tests/panic.rs diff --git a/library/core/tests/panic/location.rs b/library/coretests/tests/panic/location.rs similarity index 100% rename from library/core/tests/panic/location.rs rename to library/coretests/tests/panic/location.rs diff --git a/library/core/tests/pattern.rs b/library/coretests/tests/pattern.rs similarity index 100% rename from library/core/tests/pattern.rs rename to library/coretests/tests/pattern.rs diff --git a/library/core/tests/pin.rs b/library/coretests/tests/pin.rs similarity index 100% rename from library/core/tests/pin.rs rename to library/coretests/tests/pin.rs diff --git a/library/core/tests/pin_macro.rs b/library/coretests/tests/pin_macro.rs similarity index 100% rename from library/core/tests/pin_macro.rs rename to library/coretests/tests/pin_macro.rs diff --git a/library/core/tests/ptr.rs b/library/coretests/tests/ptr.rs similarity index 100% rename from library/core/tests/ptr.rs rename to library/coretests/tests/ptr.rs diff --git a/library/core/tests/result.rs b/library/coretests/tests/result.rs similarity index 100% rename from library/core/tests/result.rs rename to library/coretests/tests/result.rs diff --git a/library/core/tests/simd.rs b/library/coretests/tests/simd.rs similarity index 100% rename from library/core/tests/simd.rs rename to library/coretests/tests/simd.rs diff --git a/library/core/tests/slice.rs b/library/coretests/tests/slice.rs similarity index 100% rename from library/core/tests/slice.rs rename to library/coretests/tests/slice.rs diff --git a/library/core/tests/str.rs b/library/coretests/tests/str.rs similarity index 100% rename from library/core/tests/str.rs rename to library/coretests/tests/str.rs diff --git a/library/core/tests/str_lossy.rs b/library/coretests/tests/str_lossy.rs similarity index 100% rename from library/core/tests/str_lossy.rs rename to library/coretests/tests/str_lossy.rs diff --git a/library/core/tests/task.rs b/library/coretests/tests/task.rs similarity index 100% rename from library/core/tests/task.rs rename to library/coretests/tests/task.rs diff --git a/library/core/tests/time.rs b/library/coretests/tests/time.rs similarity index 100% rename from library/core/tests/time.rs rename to library/coretests/tests/time.rs diff --git a/library/core/tests/tuple.rs b/library/coretests/tests/tuple.rs similarity index 100% rename from library/core/tests/tuple.rs rename to library/coretests/tests/tuple.rs diff --git a/library/core/tests/unicode.rs b/library/coretests/tests/unicode.rs similarity index 100% rename from library/core/tests/unicode.rs rename to library/coretests/tests/unicode.rs diff --git a/library/core/tests/waker.rs b/library/coretests/tests/waker.rs similarity index 100% rename from library/core/tests/waker.rs rename to library/coretests/tests/waker.rs diff --git a/src/bootstrap/mk/Makefile.in b/src/bootstrap/mk/Makefile.in index 275c0e803cb6..7e6a39a236e0 100644 --- a/src/bootstrap/mk/Makefile.in +++ b/src/bootstrap/mk/Makefile.in @@ -55,14 +55,14 @@ check-aux: $(BOOTSTRAP_ARGS) # Run standard library tests in Miri. $(Q)$(BOOTSTRAP) miri --stage 2 \ - library/core \ + library/coretests \ library/alloc \ $(BOOTSTRAP_ARGS) \ --no-doc # Some doctests use file system operations to demonstrate dealing with `Result`. $(Q)MIRIFLAGS="-Zmiri-disable-isolation" \ $(BOOTSTRAP) miri --stage 2 \ - library/core \ + library/coretests \ library/alloc \ $(BOOTSTRAP_ARGS) \ --doc diff --git a/src/bootstrap/src/core/build_steps/check.rs b/src/bootstrap/src/core/build_steps/check.rs index d8d862caf6a9..f4a86e263967 100644 --- a/src/bootstrap/src/core/build_steps/check.rs +++ b/src/bootstrap/src/core/build_steps/check.rs @@ -45,7 +45,7 @@ impl Step for Std { const DEFAULT: bool = true; fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> { - run.crate_or_deps("sysroot").path("library") + run.crate_or_deps("sysroot").crate_or_deps("coretests").path("library") } fn make_run(run: RunConfig<'_>) { diff --git a/src/bootstrap/src/core/build_steps/test.rs b/src/bootstrap/src/core/build_steps/test.rs index 99b033db115c..5e250d18ce6a 100644 --- a/src/bootstrap/src/core/build_steps/test.rs +++ b/src/bootstrap/src/core/build_steps/test.rs @@ -2658,7 +2658,7 @@ impl Step for Crate { const DEFAULT: bool = true; fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> { - run.crate_or_deps("sysroot") + run.crate_or_deps("sysroot").crate_or_deps("coretests") } fn make_run(run: RunConfig<'_>) { From 9e5c6a2898fe49c984600ba34d05d8c6ad3dd50e Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Thu, 23 Jan 2025 15:23:30 +0000 Subject: [PATCH 50/81] Fix cg_clif testing coretests --- .../build_system/tests.rs | 2 +- ...oretests-Disable-not-compiling-tests.patch | 44 ------------------- ...7-coretests-128bit-atomic-operations.patch | 15 +++---- ...coretests-Disable-long-running-tests.patch | 6 +-- 4 files changed, 11 insertions(+), 56 deletions(-) delete mode 100644 compiler/rustc_codegen_cranelift/patches/0022-coretests-Disable-not-compiling-tests.patch diff --git a/compiler/rustc_codegen_cranelift/build_system/tests.rs b/compiler/rustc_codegen_cranelift/build_system/tests.rs index 8de419a0c4eb..bcb2b4881ebe 100644 --- a/compiler/rustc_codegen_cranelift/build_system/tests.rs +++ b/compiler/rustc_codegen_cranelift/build_system/tests.rs @@ -151,7 +151,7 @@ const EXTENDED_SYSROOT_SUITE: &[TestCase] = &[ apply_patches( &runner.dirs, "coretests", - &runner.stdlib_source.join("library/core/tests"), + &runner.stdlib_source.join("library/coretests"), &LIBCORE_TESTS_SRC.to_path(&runner.dirs), ); diff --git a/compiler/rustc_codegen_cranelift/patches/0022-coretests-Disable-not-compiling-tests.patch b/compiler/rustc_codegen_cranelift/patches/0022-coretests-Disable-not-compiling-tests.patch deleted file mode 100644 index 161173d47650..000000000000 --- a/compiler/rustc_codegen_cranelift/patches/0022-coretests-Disable-not-compiling-tests.patch +++ /dev/null @@ -1,44 +0,0 @@ -From f6befc4bb51d84f5f1cf35938a168c953d421350 Mon Sep 17 00:00:00 2001 -From: bjorn3 -Date: Sun, 24 Nov 2019 15:10:23 +0100 -Subject: [PATCH] [core] Disable not compiling tests - ---- - library/core/tests/Cargo.toml | 8 ++++++++ - library/core/tests/num/flt2dec/mod.rs | 1 - - library/core/tests/num/int_macros.rs | 2 ++ - library/core/tests/num/uint_macros.rs | 2 ++ - library/core/tests/ptr.rs | 2 ++ - library/core/tests/slice.rs | 2 ++ - 6 files changed, 16 insertions(+), 1 deletion(-) - create mode 100644 library/core/tests/Cargo.toml - -diff --git a/Cargo.toml b/Cargo.toml -new file mode 100644 -index 0000000..46fd999 ---- /dev/null -+++ b/Cargo.toml -@@ -0,0 +1,12 @@ -+[package] -+name = "coretests" -+version = "0.0.0" -+edition = "2021" -+ -+[lib] -+name = "coretests" -+path = "lib.rs" -+ -+[dependencies] -+rand = { version = "0.8.5", default-features = false } -+rand_xorshift = { version = "0.3.0", default-features = false } -diff --git a/lib.rs b/lib.rs -index 42a26ae..5ac1042 100644 ---- a/lib.rs -+++ b/lib.rs -@@ -1,3 +1,4 @@ -+#![cfg(test)] - // tidy-alphabetical-start - #![cfg_attr(target_has_atomic = "128", feature(integer_atomics))] - #![cfg_attr(test, feature(cfg_match))] --- -2.21.0 (Apple Git-122) diff --git a/compiler/rustc_codegen_cranelift/patches/0027-coretests-128bit-atomic-operations.patch b/compiler/rustc_codegen_cranelift/patches/0027-coretests-128bit-atomic-operations.patch index 06840624ceff..4a06dc3f7ef8 100644 --- a/compiler/rustc_codegen_cranelift/patches/0027-coretests-128bit-atomic-operations.patch +++ b/compiler/rustc_codegen_cranelift/patches/0027-coretests-128bit-atomic-operations.patch @@ -10,21 +10,20 @@ Cranelift doesn't support them yet library/core/tests/atomic.rs | 4 --- 4 files changed, 4 insertions(+), 50 deletions(-) -diff --git a/lib.rs b/lib.rs +diff --git a/tests/lib.rs b/tests/lib.rs index 1e336bf..35e6f54 100644 ---- a/lib.rs -+++ b/lib.rs -@@ -2,6 +2,5 @@ - #![cfg(test)] +--- a/tests/lib.rs ++++ b/tests/lib.rs +@@ -2,5 +2,4 @@ // tidy-alphabetical-start -#![cfg_attr(target_has_atomic = "128", feature(integer_atomics))] #![cfg_attr(test, feature(cfg_match))] #![feature(alloc_layout_extra)] #![feature(array_chunks)] -diff --git a/atomic.rs b/atomic.rs +diff --git a/tests/atomic.rs b/tests/atomic.rs index b735957..ea728b6 100644 ---- a/atomic.rs -+++ b/atomic.rs +--- a/tests/atomic.rs ++++ b/tests/atomic.rs @@ -185,10 +185,6 @@ fn atomic_alignment() { assert_eq!(align_of::(), size_of::()); #[cfg(target_has_atomic = "64")] diff --git a/compiler/rustc_codegen_cranelift/patches/0028-coretests-Disable-long-running-tests.patch b/compiler/rustc_codegen_cranelift/patches/0028-coretests-Disable-long-running-tests.patch index b98326c54a67..5a38dffa24fe 100644 --- a/compiler/rustc_codegen_cranelift/patches/0028-coretests-Disable-long-running-tests.patch +++ b/compiler/rustc_codegen_cranelift/patches/0028-coretests-Disable-long-running-tests.patch @@ -7,10 +7,10 @@ Subject: [PATCH] Disable long running tests library/core/tests/slice.rs | 2 ++ 1 file changed, 2 insertions(+) -diff --git a/slice.rs b/slice.rs +diff --git a/tests/slice.rs b/tests/slice.rs index 8402833..84592e0 100644 ---- a/slice.rs -+++ b/slice.rs +--- a/tests/slice.rs ++++ b/tests/slice.rs @@ -1809,6 +1809,7 @@ fn sort_unstable() { } } From fcf78bbd757689aff3d6595b7f288de6a82e11bc Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Thu, 23 Jan 2025 16:12:22 +0000 Subject: [PATCH 51/81] Update comment --- library/core/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/core/src/lib.rs b/library/core/src/lib.rs index 01ed3cc69a2c..c18e0405f729 100644 --- a/library/core/src/lib.rs +++ b/library/core/src/lib.rs @@ -44,7 +44,7 @@ //! called. The `lang` attribute is called `eh_personality`. // Since core defines many fundamental lang items, all tests live in a -// separate crate, libcoretest (library/core/tests), to avoid bizarre issues. +// separate crate, coretests (library/coretests), to avoid bizarre issues. // // Here we explicitly #[cfg]-out this whole crate when testing. If we don't do // this, both the generated test artifact and the linked libtest (which From 2f4dd6e6890eefe30b4c041486ec3af90a071eb2 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Sun, 26 Jan 2025 10:24:32 +0000 Subject: [PATCH 52/81] Actually run the bstr test It previously didn't get run because of a missing mod bstr. --- library/coretests/tests/bstr.rs | 4 +--- library/coretests/tests/lib.rs | 2 ++ 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/library/coretests/tests/bstr.rs b/library/coretests/tests/bstr.rs index 5fecd0a4084c..cd4d69d6b337 100644 --- a/library/coretests/tests/bstr.rs +++ b/library/coretests/tests/bstr.rs @@ -1,6 +1,4 @@ -#![feature(bstr)] - -use core::ByteStr; +use core::bstr::ByteStr; #[test] fn test_debug() { diff --git a/library/coretests/tests/lib.rs b/library/coretests/tests/lib.rs index a8980c5f30ae..0607d508a48e 100644 --- a/library/coretests/tests/lib.rs +++ b/library/coretests/tests/lib.rs @@ -11,6 +11,7 @@ #![feature(async_iter_from_iter)] #![feature(async_iterator)] #![feature(bigint_helper_methods)] +#![feature(bstr)] #![feature(cell_update)] #![feature(clone_to_uninit)] #![feature(const_black_box)] @@ -139,6 +140,7 @@ mod asserting; mod async_iter; mod atomic; mod bool; +mod bstr; mod cell; mod char; mod clone; From d810d426a4c66d3cae8022547c170e38488d95fb Mon Sep 17 00:00:00 2001 From: Kalle Wachsmuth Date: Mon, 17 Jun 2024 18:49:19 +0200 Subject: [PATCH 53/81] unrelated cleanup --- compiler/rustc_lint/src/builtin.rs | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/compiler/rustc_lint/src/builtin.rs b/compiler/rustc_lint/src/builtin.rs index 876ef944d650..3da9ef3ff7c6 100644 --- a/compiler/rustc_lint/src/builtin.rs +++ b/compiler/rustc_lint/src/builtin.rs @@ -90,19 +90,11 @@ declare_lint! { declare_lint_pass!(WhileTrue => [WHILE_TRUE]); -/// Traverse through any amount of parenthesis and return the first non-parens expression. -fn pierce_parens(mut expr: &ast::Expr) -> &ast::Expr { - while let ast::ExprKind::Paren(sub) = &expr.kind { - expr = sub; - } - expr -} - impl EarlyLintPass for WhileTrue { #[inline] fn check_expr(&mut self, cx: &EarlyContext<'_>, e: &ast::Expr) { if let ast::ExprKind::While(cond, _, label) = &e.kind - && let ast::ExprKind::Lit(token_lit) = pierce_parens(cond).kind + && let ast::ExprKind::Lit(token_lit) = cond.peel_parens().kind && let token::Lit { kind: token::Bool, symbol: kw::True, .. } = token_lit && !cond.span.from_expansion() { @@ -2651,7 +2643,7 @@ impl<'tcx> LateLintPass<'tcx> for InvalidValue { } declare_lint! { - /// The `deref_nullptr` lint detects when an null pointer is dereferenced, + /// The `deref_nullptr` lint detects when a null pointer is dereferenced, /// which causes [undefined behavior]. /// /// ### Example From 9e316f34720a27477c79fdb5e0193554bd4d3fb5 Mon Sep 17 00:00:00 2001 From: Kalle Wachsmuth Date: Tue, 29 Oct 2024 20:49:22 +0100 Subject: [PATCH 54/81] remove `clippy::double_neg` --- src/tools/clippy/.github/driver.sh | 6 +- src/tools/clippy/book/src/usage.md | 9 +- src/tools/clippy/clippy_dev/src/new_lint.rs | 4 +- .../clippy/clippy_lints/src/declared_lints.rs | 1 - .../clippy_lints/src/deprecated_lints.rs | 2 + .../clippy_lints/src/misc_early/double_neg.rs | 18 --- .../clippy/clippy_lints/src/misc_early/mod.rs | 22 --- src/tools/clippy/tests/ui/double_neg.rs | 10 -- src/tools/clippy/tests/ui/double_neg.stderr | 11 -- src/tools/clippy/tests/ui/rename.fixed | 15 ++- src/tools/clippy/tests/ui/rename.rs | 15 ++- src/tools/clippy/tests/ui/rename.stderr | 126 +++++++++--------- 12 files changed, 93 insertions(+), 146 deletions(-) delete mode 100644 src/tools/clippy/clippy_lints/src/misc_early/double_neg.rs delete mode 100644 src/tools/clippy/tests/ui/double_neg.rs delete mode 100644 src/tools/clippy/tests/ui/double_neg.stderr diff --git a/src/tools/clippy/.github/driver.sh b/src/tools/clippy/.github/driver.sh index 09202b1878b2..701be6bd76d3 100755 --- a/src/tools/clippy/.github/driver.sh +++ b/src/tools/clippy/.github/driver.sh @@ -47,9 +47,9 @@ unset CARGO_MANIFEST_DIR # Run a lint and make sure it produces the expected output. It's also expected to exit with code 1 # FIXME: How to match the clippy invocation in compile-test.rs? -./target/debug/clippy-driver -Dwarnings -Aunused -Zui-testing --emit metadata --crate-type bin tests/ui/double_neg.rs 2>double_neg.stderr && exit 1 -sed -e "/= help: for/d" double_neg.stderr > normalized.stderr -diff -u normalized.stderr tests/ui/double_neg.stderr +./target/debug/clippy-driver -Dwarnings -Aunused -Zui-testing --emit metadata --crate-type bin tests/ui/box_default.rs 2>box_default.stderr && exit 1 +sed -e "/= help: for/d" box_default.stderr > normalized.stderr +diff -u normalized.stderr tests/ui/box_default.stderr # make sure "clippy-driver --rustc --arg" and "rustc --arg" behave the same SYSROOT=$(rustc --print sysroot) diff --git a/src/tools/clippy/book/src/usage.md b/src/tools/clippy/book/src/usage.md index 7a0be6994fe1..23edf6c2abaa 100644 --- a/src/tools/clippy/book/src/usage.md +++ b/src/tools/clippy/book/src/usage.md @@ -33,7 +33,7 @@ You can configure lint levels on the command line by adding `-A/W/D clippy::lint_name` like this: ```bash -cargo clippy -- -Aclippy::style -Wclippy::double_neg -Dclippy::perf +cargo clippy -- -Aclippy::style -Wclippy::box_default -Dclippy::perf ``` For [CI] all warnings can be elevated to errors which will in turn fail @@ -101,11 +101,10 @@ You can configure lint levels in source code the same way you can configure ```rust,ignore #![allow(clippy::style)] -#[warn(clippy::double_neg)] +#[warn(clippy::box_default)] fn main() { - let x = 1; - let y = --x; - // ^^ warning: double negation + let _ = Box::::new(Default::default()); + // ^ warning: `Box::new(_)` of default value } ``` diff --git a/src/tools/clippy/clippy_dev/src/new_lint.rs b/src/tools/clippy/clippy_dev/src/new_lint.rs index 24d1a53266a0..35dd986ff614 100644 --- a/src/tools/clippy/clippy_dev/src/new_lint.rs +++ b/src/tools/clippy/clippy_dev/src/new_lint.rs @@ -455,7 +455,7 @@ fn setup_mod_file(path: &Path, lint: &LintData<'_>) -> io::Result<&'static str> }); // Find both the last lint declaration (declare_clippy_lint!) and the lint pass impl - while let Some(LintDeclSearchResult { content, .. }) = iter.find(|result| result.token == TokenKind::Ident) { + while let Some(LintDeclSearchResult { content, .. }) = iter.find(|result| result.token_kind == TokenKind::Ident) { let mut iter = iter .by_ref() .filter(|t| !matches!(t.token_kind, TokenKind::Whitespace | TokenKind::LineComment { .. })); @@ -465,7 +465,7 @@ fn setup_mod_file(path: &Path, lint: &LintData<'_>) -> io::Result<&'static str> // matches `!{` match_tokens!(iter, Bang OpenBrace); if let Some(LintDeclSearchResult { range, .. }) = - iter.find(|result| result.token == TokenKind::CloseBrace) + iter.find(|result| result.token_kind == TokenKind::CloseBrace) { last_decl_curly_offset = Some(range.end); } diff --git a/src/tools/clippy/clippy_lints/src/declared_lints.rs b/src/tools/clippy/clippy_lints/src/declared_lints.rs index 3ff10d850f82..87e546fbf014 100644 --- a/src/tools/clippy/clippy_lints/src/declared_lints.rs +++ b/src/tools/clippy/clippy_lints/src/declared_lints.rs @@ -507,7 +507,6 @@ pub static LINTS: &[&crate::LintInfo] = &[ crate::misc::USED_UNDERSCORE_BINDING_INFO, crate::misc::USED_UNDERSCORE_ITEMS_INFO, crate::misc_early::BUILTIN_TYPE_SHADOW_INFO, - crate::misc_early::DOUBLE_NEG_INFO, crate::misc_early::DUPLICATE_UNDERSCORE_ARGUMENT_INFO, crate::misc_early::MIXED_CASE_HEX_LITERALS_INFO, crate::misc_early::REDUNDANT_AT_REST_PATTERN_INFO, diff --git a/src/tools/clippy/clippy_lints/src/deprecated_lints.rs b/src/tools/clippy/clippy_lints/src/deprecated_lints.rs index 3ea792d8b835..5604172d6f30 100644 --- a/src/tools/clippy/clippy_lints/src/deprecated_lints.rs +++ b/src/tools/clippy/clippy_lints/src/deprecated_lints.rs @@ -129,6 +129,8 @@ declare_with_version! { RENAMED(RENAMED_VERSION): &[(&str, &str)] = &[ ("clippy::clone_double_ref", "suspicious_double_ref_op"), #[clippy::version = ""] ("clippy::cmp_nan", "invalid_nan_comparisons"), + #[clippy::version = "1.86.0"] + ("clippy::double_neg", "double_negations"), #[clippy::version = ""] ("clippy::drop_bounds", "drop_bounds"), #[clippy::version = ""] diff --git a/src/tools/clippy/clippy_lints/src/misc_early/double_neg.rs b/src/tools/clippy/clippy_lints/src/misc_early/double_neg.rs deleted file mode 100644 index 06ba968fa4ed..000000000000 --- a/src/tools/clippy/clippy_lints/src/misc_early/double_neg.rs +++ /dev/null @@ -1,18 +0,0 @@ -use clippy_utils::diagnostics::span_lint; -use rustc_ast::ast::{Expr, ExprKind, UnOp}; -use rustc_lint::EarlyContext; - -use super::DOUBLE_NEG; - -pub(super) fn check(cx: &EarlyContext<'_>, expr: &Expr) { - if let ExprKind::Unary(UnOp::Neg, ref inner) = expr.kind { - if let ExprKind::Unary(UnOp::Neg, _) = inner.kind { - span_lint( - cx, - DOUBLE_NEG, - expr.span, - "`--x` could be misinterpreted as pre-decrement by C programmers, is usually a no-op", - ); - } - } -} diff --git a/src/tools/clippy/clippy_lints/src/misc_early/mod.rs b/src/tools/clippy/clippy_lints/src/misc_early/mod.rs index 37d7427f9a5d..637d6ed3ad2c 100644 --- a/src/tools/clippy/clippy_lints/src/misc_early/mod.rs +++ b/src/tools/clippy/clippy_lints/src/misc_early/mod.rs @@ -1,5 +1,4 @@ mod builtin_type_shadow; -mod double_neg; mod literal_suffix; mod mixed_case_hex_literals; mod redundant_at_rest_pattern; @@ -85,25 +84,6 @@ declare_clippy_lint! { "function arguments having names which only differ by an underscore" } -declare_clippy_lint! { - /// ### What it does - /// Detects expressions of the form `--x`. - /// - /// ### Why is this bad? - /// It can mislead C/C++ programmers to think `x` was - /// decremented. - /// - /// ### Example - /// ```no_run - /// let mut x = 3; - /// --x; - /// ``` - #[clippy::version = "pre 1.29.0"] - pub DOUBLE_NEG, - style, - "`--x`, which is a double negation of `x` and not a pre-decrement as in C/C++" -} - declare_clippy_lint! { /// ### What it does /// Warns on hexadecimal literals with mixed-case letter @@ -352,7 +332,6 @@ declare_clippy_lint! { declare_lint_pass!(MiscEarlyLints => [ UNNEEDED_FIELD_PATTERN, DUPLICATE_UNDERSCORE_ARGUMENT, - DOUBLE_NEG, MIXED_CASE_HEX_LITERALS, UNSEPARATED_LITERAL_SUFFIX, SEPARATED_LITERAL_SUFFIX, @@ -415,7 +394,6 @@ impl EarlyLintPass for MiscEarlyLints { if let ExprKind::Lit(lit) = expr.kind { MiscEarlyLints::check_lit(cx, lit, expr.span); } - double_neg::check(cx, expr); } } diff --git a/src/tools/clippy/tests/ui/double_neg.rs b/src/tools/clippy/tests/ui/double_neg.rs deleted file mode 100644 index 3be8c6288738..000000000000 --- a/src/tools/clippy/tests/ui/double_neg.rs +++ /dev/null @@ -1,10 +0,0 @@ -#[warn(clippy::double_neg)] -#[allow(clippy::no_effect)] -fn main() { - let x = 1; - -x; - -(-x); - --x; - //~^ ERROR: `--x` could be misinterpreted as pre-decrement by C programmers, is usually - //~| NOTE: `-D clippy::double-neg` implied by `-D warnings` -} diff --git a/src/tools/clippy/tests/ui/double_neg.stderr b/src/tools/clippy/tests/ui/double_neg.stderr deleted file mode 100644 index 9a902d1323cc..000000000000 --- a/src/tools/clippy/tests/ui/double_neg.stderr +++ /dev/null @@ -1,11 +0,0 @@ -error: `--x` could be misinterpreted as pre-decrement by C programmers, is usually a no-op - --> tests/ui/double_neg.rs:7:5 - | -LL | --x; - | ^^^ - | - = note: `-D clippy::double-neg` implied by `-D warnings` - = help: to override `-D warnings` add `#[allow(clippy::double_neg)]` - -error: aborting due to 1 previous error - diff --git a/src/tools/clippy/tests/ui/rename.fixed b/src/tools/clippy/tests/ui/rename.fixed index 47d6e119543d..501811fa491b 100644 --- a/src/tools/clippy/tests/ui/rename.fixed +++ b/src/tools/clippy/tests/ui/rename.fixed @@ -13,9 +13,8 @@ #![allow(clippy::disallowed_methods)] #![allow(clippy::disallowed_types)] #![allow(clippy::mixed_read_write_in_expression)] -#![allow(clippy::manual_find_map)] #![allow(clippy::manual_filter_map)] -#![allow(unpredictable_function_pointer_comparisons)] +#![allow(clippy::manual_find_map)] #![allow(clippy::useless_conversion)] #![allow(clippy::redundant_pattern_matching)] #![allow(clippy::match_result_ok)] @@ -30,6 +29,7 @@ #![allow(clippy::unwrap_used)] #![allow(clippy::panicking_overflow_checks)] #![allow(clippy::needless_borrow)] +#![allow(clippy::reversed_empty_ranges)] #![allow(clippy::single_char_add_str)] #![allow(clippy::module_name_repetitions)] #![allow(clippy::missing_const_for_thread_local)] @@ -39,9 +39,11 @@ #![allow(invalid_reference_casting)] #![allow(suspicious_double_ref_op)] #![allow(invalid_nan_comparisons)] +#![allow(double_negations)] #![allow(drop_bounds)] #![allow(dropping_copy_types)] #![allow(dropping_references)] +#![allow(unpredictable_function_pointer_comparisons)] #![allow(useless_ptr_null_checks)] #![allow(for_loops_over_fallibles)] #![allow(forgetting_copy_types)] @@ -60,8 +62,6 @@ #![allow(unknown_lints)] #![allow(unused_labels)] #![allow(ambiguous_wide_pointer_comparisons)] -#![allow(unpredictable_function_pointer_comparisons)] -#![allow(clippy::reversed_empty_ranges)] #![warn(clippy::almost_complete_range)] //~ ERROR: lint `clippy::almost_complete_letter_range` #![warn(clippy::disallowed_names)] //~ ERROR: lint `clippy::blacklisted_name` #![warn(clippy::blocks_in_conditions)] //~ ERROR: lint `clippy::block_in_if_condition_expr` @@ -74,9 +74,8 @@ #![warn(clippy::disallowed_methods)] //~ ERROR: lint `clippy::disallowed_method` #![warn(clippy::disallowed_types)] //~ ERROR: lint `clippy::disallowed_type` #![warn(clippy::mixed_read_write_in_expression)] //~ ERROR: lint `clippy::eval_order_dependence` -#![warn(clippy::manual_find_map)] //~ ERROR: lint `clippy::find_map` #![warn(clippy::manual_filter_map)] //~ ERROR: lint `clippy::filter_map` -#![warn(unpredictable_function_pointer_comparisons)] //~ ERROR: lint `clippy::fn_address_comparisons` +#![warn(clippy::manual_find_map)] //~ ERROR: lint `clippy::find_map` #![warn(clippy::useless_conversion)] //~ ERROR: lint `clippy::identity_conversion` #![warn(clippy::redundant_pattern_matching)] //~ ERROR: lint `clippy::if_let_redundant_pattern_matching` #![warn(clippy::match_result_ok)] //~ ERROR: lint `clippy::if_let_some_result` @@ -95,6 +94,7 @@ #![warn(clippy::expect_used)] //~ ERROR: lint `clippy::result_expect_used` #![warn(clippy::map_unwrap_or)] //~ ERROR: lint `clippy::result_map_unwrap_or_else` #![warn(clippy::unwrap_used)] //~ ERROR: lint `clippy::result_unwrap_used` +#![warn(clippy::reversed_empty_ranges)] //~ ERROR: lint `clippy::reverse_range_loop` #![warn(clippy::single_char_add_str)] //~ ERROR: lint `clippy::single_char_push_str` #![warn(clippy::module_name_repetitions)] //~ ERROR: lint `clippy::stutter` #![warn(clippy::missing_const_for_thread_local)] //~ ERROR: lint `clippy::thread_local_initializer_can_be_made_const` @@ -104,9 +104,11 @@ #![warn(invalid_reference_casting)] //~ ERROR: lint `clippy::cast_ref_to_mut` #![warn(suspicious_double_ref_op)] //~ ERROR: lint `clippy::clone_double_ref` #![warn(invalid_nan_comparisons)] //~ ERROR: lint `clippy::cmp_nan` +#![warn(double_negations)] //~ ERROR: lint `clippy::double_neg` #![warn(drop_bounds)] //~ ERROR: lint `clippy::drop_bounds` #![warn(dropping_copy_types)] //~ ERROR: lint `clippy::drop_copy` #![warn(dropping_references)] //~ ERROR: lint `clippy::drop_ref` +#![warn(unpredictable_function_pointer_comparisons)] //~ ERROR: lint `clippy::fn_address_comparisons` #![warn(useless_ptr_null_checks)] //~ ERROR: lint `clippy::fn_null_check` #![warn(for_loops_over_fallibles)] //~ ERROR: lint `clippy::for_loop_over_option` #![warn(for_loops_over_fallibles)] //~ ERROR: lint `clippy::for_loop_over_result` @@ -128,6 +130,5 @@ #![warn(unknown_lints)] //~ ERROR: lint `clippy::unknown_clippy_lints` #![warn(unused_labels)] //~ ERROR: lint `clippy::unused_label` #![warn(ambiguous_wide_pointer_comparisons)] //~ ERROR: lint `clippy::vtable_address_comparisons` -#![warn(clippy::reversed_empty_ranges)] //~ ERROR: lint `clippy::reverse_range_loop` fn main() {} diff --git a/src/tools/clippy/tests/ui/rename.rs b/src/tools/clippy/tests/ui/rename.rs index 12c7db69be2e..7f4b8062e1b4 100644 --- a/src/tools/clippy/tests/ui/rename.rs +++ b/src/tools/clippy/tests/ui/rename.rs @@ -13,9 +13,8 @@ #![allow(clippy::disallowed_methods)] #![allow(clippy::disallowed_types)] #![allow(clippy::mixed_read_write_in_expression)] -#![allow(clippy::manual_find_map)] #![allow(clippy::manual_filter_map)] -#![allow(unpredictable_function_pointer_comparisons)] +#![allow(clippy::manual_find_map)] #![allow(clippy::useless_conversion)] #![allow(clippy::redundant_pattern_matching)] #![allow(clippy::match_result_ok)] @@ -30,6 +29,7 @@ #![allow(clippy::unwrap_used)] #![allow(clippy::panicking_overflow_checks)] #![allow(clippy::needless_borrow)] +#![allow(clippy::reversed_empty_ranges)] #![allow(clippy::single_char_add_str)] #![allow(clippy::module_name_repetitions)] #![allow(clippy::missing_const_for_thread_local)] @@ -39,9 +39,11 @@ #![allow(invalid_reference_casting)] #![allow(suspicious_double_ref_op)] #![allow(invalid_nan_comparisons)] +#![allow(double_negations)] #![allow(drop_bounds)] #![allow(dropping_copy_types)] #![allow(dropping_references)] +#![allow(unpredictable_function_pointer_comparisons)] #![allow(useless_ptr_null_checks)] #![allow(for_loops_over_fallibles)] #![allow(forgetting_copy_types)] @@ -60,8 +62,6 @@ #![allow(unknown_lints)] #![allow(unused_labels)] #![allow(ambiguous_wide_pointer_comparisons)] -#![allow(unpredictable_function_pointer_comparisons)] -#![allow(clippy::reversed_empty_ranges)] #![warn(clippy::almost_complete_letter_range)] //~ ERROR: lint `clippy::almost_complete_letter_range` #![warn(clippy::blacklisted_name)] //~ ERROR: lint `clippy::blacklisted_name` #![warn(clippy::block_in_if_condition_expr)] //~ ERROR: lint `clippy::block_in_if_condition_expr` @@ -74,9 +74,8 @@ #![warn(clippy::disallowed_method)] //~ ERROR: lint `clippy::disallowed_method` #![warn(clippy::disallowed_type)] //~ ERROR: lint `clippy::disallowed_type` #![warn(clippy::eval_order_dependence)] //~ ERROR: lint `clippy::eval_order_dependence` -#![warn(clippy::find_map)] //~ ERROR: lint `clippy::find_map` #![warn(clippy::filter_map)] //~ ERROR: lint `clippy::filter_map` -#![warn(clippy::fn_address_comparisons)] //~ ERROR: lint `clippy::fn_address_comparisons` +#![warn(clippy::find_map)] //~ ERROR: lint `clippy::find_map` #![warn(clippy::identity_conversion)] //~ ERROR: lint `clippy::identity_conversion` #![warn(clippy::if_let_redundant_pattern_matching)] //~ ERROR: lint `clippy::if_let_redundant_pattern_matching` #![warn(clippy::if_let_some_result)] //~ ERROR: lint `clippy::if_let_some_result` @@ -95,6 +94,7 @@ #![warn(clippy::result_expect_used)] //~ ERROR: lint `clippy::result_expect_used` #![warn(clippy::result_map_unwrap_or_else)] //~ ERROR: lint `clippy::result_map_unwrap_or_else` #![warn(clippy::result_unwrap_used)] //~ ERROR: lint `clippy::result_unwrap_used` +#![warn(clippy::reverse_range_loop)] //~ ERROR: lint `clippy::reverse_range_loop` #![warn(clippy::single_char_push_str)] //~ ERROR: lint `clippy::single_char_push_str` #![warn(clippy::stutter)] //~ ERROR: lint `clippy::stutter` #![warn(clippy::thread_local_initializer_can_be_made_const)] //~ ERROR: lint `clippy::thread_local_initializer_can_be_made_const` @@ -104,9 +104,11 @@ #![warn(clippy::cast_ref_to_mut)] //~ ERROR: lint `clippy::cast_ref_to_mut` #![warn(clippy::clone_double_ref)] //~ ERROR: lint `clippy::clone_double_ref` #![warn(clippy::cmp_nan)] //~ ERROR: lint `clippy::cmp_nan` +#![warn(clippy::double_neg)] //~ ERROR: lint `clippy::double_neg` #![warn(clippy::drop_bounds)] //~ ERROR: lint `clippy::drop_bounds` #![warn(clippy::drop_copy)] //~ ERROR: lint `clippy::drop_copy` #![warn(clippy::drop_ref)] //~ ERROR: lint `clippy::drop_ref` +#![warn(clippy::fn_address_comparisons)] //~ ERROR: lint `clippy::fn_address_comparisons` #![warn(clippy::fn_null_check)] //~ ERROR: lint `clippy::fn_null_check` #![warn(clippy::for_loop_over_option)] //~ ERROR: lint `clippy::for_loop_over_option` #![warn(clippy::for_loop_over_result)] //~ ERROR: lint `clippy::for_loop_over_result` @@ -128,6 +130,5 @@ #![warn(clippy::unknown_clippy_lints)] //~ ERROR: lint `clippy::unknown_clippy_lints` #![warn(clippy::unused_label)] //~ ERROR: lint `clippy::unused_label` #![warn(clippy::vtable_address_comparisons)] //~ ERROR: lint `clippy::vtable_address_comparisons` -#![warn(clippy::reverse_range_loop)] //~ ERROR: lint `clippy::reverse_range_loop` fn main() {} diff --git a/src/tools/clippy/tests/ui/rename.stderr b/src/tools/clippy/tests/ui/rename.stderr index 1ec45c4f1f7b..f24eaec3917a 100644 --- a/src/tools/clippy/tests/ui/rename.stderr +++ b/src/tools/clippy/tests/ui/rename.stderr @@ -73,132 +73,132 @@ error: lint `clippy::eval_order_dependence` has been renamed to `clippy::mixed_r LL | #![warn(clippy::eval_order_dependence)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::mixed_read_write_in_expression` -error: lint `clippy::find_map` has been renamed to `clippy::manual_find_map` - --> tests/ui/rename.rs:77:9 - | -LL | #![warn(clippy::find_map)] - | ^^^^^^^^^^^^^^^^ help: use the new name: `clippy::manual_find_map` - error: lint `clippy::filter_map` has been renamed to `clippy::manual_filter_map` - --> tests/ui/rename.rs:78:9 + --> tests/ui/rename.rs:77:9 | LL | #![warn(clippy::filter_map)] | ^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::manual_filter_map` -error: lint `clippy::fn_address_comparisons` has been renamed to `unpredictable_function_pointer_comparisons` - --> tests/ui/rename.rs:79:9 +error: lint `clippy::find_map` has been renamed to `clippy::manual_find_map` + --> tests/ui/rename.rs:78:9 | -LL | #![warn(clippy::fn_address_comparisons)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `unpredictable_function_pointer_comparisons` +LL | #![warn(clippy::find_map)] + | ^^^^^^^^^^^^^^^^ help: use the new name: `clippy::manual_find_map` error: lint `clippy::identity_conversion` has been renamed to `clippy::useless_conversion` - --> tests/ui/rename.rs:80:9 + --> tests/ui/rename.rs:79:9 | LL | #![warn(clippy::identity_conversion)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::useless_conversion` error: lint `clippy::if_let_redundant_pattern_matching` has been renamed to `clippy::redundant_pattern_matching` - --> tests/ui/rename.rs:81:9 + --> tests/ui/rename.rs:80:9 | LL | #![warn(clippy::if_let_redundant_pattern_matching)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::redundant_pattern_matching` error: lint `clippy::if_let_some_result` has been renamed to `clippy::match_result_ok` - --> tests/ui/rename.rs:82:9 + --> tests/ui/rename.rs:81:9 | LL | #![warn(clippy::if_let_some_result)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::match_result_ok` error: lint `clippy::incorrect_clone_impl_on_copy_type` has been renamed to `clippy::non_canonical_clone_impl` - --> tests/ui/rename.rs:83:9 + --> tests/ui/rename.rs:82:9 | LL | #![warn(clippy::incorrect_clone_impl_on_copy_type)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::non_canonical_clone_impl` error: lint `clippy::incorrect_partial_ord_impl_on_ord_type` has been renamed to `clippy::non_canonical_partial_ord_impl` - --> tests/ui/rename.rs:84:9 + --> tests/ui/rename.rs:83:9 | LL | #![warn(clippy::incorrect_partial_ord_impl_on_ord_type)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::non_canonical_partial_ord_impl` error: lint `clippy::integer_arithmetic` has been renamed to `clippy::arithmetic_side_effects` - --> tests/ui/rename.rs:85:9 + --> tests/ui/rename.rs:84:9 | LL | #![warn(clippy::integer_arithmetic)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::arithmetic_side_effects` error: lint `clippy::logic_bug` has been renamed to `clippy::overly_complex_bool_expr` - --> tests/ui/rename.rs:86:9 + --> tests/ui/rename.rs:85:9 | LL | #![warn(clippy::logic_bug)] | ^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::overly_complex_bool_expr` error: lint `clippy::new_without_default_derive` has been renamed to `clippy::new_without_default` - --> tests/ui/rename.rs:87:9 + --> tests/ui/rename.rs:86:9 | LL | #![warn(clippy::new_without_default_derive)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::new_without_default` error: lint `clippy::option_and_then_some` has been renamed to `clippy::bind_instead_of_map` - --> tests/ui/rename.rs:88:9 + --> tests/ui/rename.rs:87:9 | LL | #![warn(clippy::option_and_then_some)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::bind_instead_of_map` error: lint `clippy::option_expect_used` has been renamed to `clippy::expect_used` - --> tests/ui/rename.rs:89:9 + --> tests/ui/rename.rs:88:9 | LL | #![warn(clippy::option_expect_used)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::expect_used` error: lint `clippy::option_map_unwrap_or` has been renamed to `clippy::map_unwrap_or` - --> tests/ui/rename.rs:90:9 + --> tests/ui/rename.rs:89:9 | LL | #![warn(clippy::option_map_unwrap_or)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::map_unwrap_or` error: lint `clippy::option_map_unwrap_or_else` has been renamed to `clippy::map_unwrap_or` - --> tests/ui/rename.rs:91:9 + --> tests/ui/rename.rs:90:9 | LL | #![warn(clippy::option_map_unwrap_or_else)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::map_unwrap_or` error: lint `clippy::option_unwrap_used` has been renamed to `clippy::unwrap_used` - --> tests/ui/rename.rs:92:9 + --> tests/ui/rename.rs:91:9 | LL | #![warn(clippy::option_unwrap_used)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::unwrap_used` error: lint `clippy::overflow_check_conditional` has been renamed to `clippy::panicking_overflow_checks` - --> tests/ui/rename.rs:93:9 + --> tests/ui/rename.rs:92:9 | LL | #![warn(clippy::overflow_check_conditional)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::panicking_overflow_checks` error: lint `clippy::ref_in_deref` has been renamed to `clippy::needless_borrow` - --> tests/ui/rename.rs:94:9 + --> tests/ui/rename.rs:93:9 | LL | #![warn(clippy::ref_in_deref)] | ^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::needless_borrow` error: lint `clippy::result_expect_used` has been renamed to `clippy::expect_used` - --> tests/ui/rename.rs:95:9 + --> tests/ui/rename.rs:94:9 | LL | #![warn(clippy::result_expect_used)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::expect_used` error: lint `clippy::result_map_unwrap_or_else` has been renamed to `clippy::map_unwrap_or` - --> tests/ui/rename.rs:96:9 + --> tests/ui/rename.rs:95:9 | LL | #![warn(clippy::result_map_unwrap_or_else)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::map_unwrap_or` error: lint `clippy::result_unwrap_used` has been renamed to `clippy::unwrap_used` - --> tests/ui/rename.rs:97:9 + --> tests/ui/rename.rs:96:9 | LL | #![warn(clippy::result_unwrap_used)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::unwrap_used` +error: lint `clippy::reverse_range_loop` has been renamed to `clippy::reversed_empty_ranges` + --> tests/ui/rename.rs:97:9 + | +LL | #![warn(clippy::reverse_range_loop)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::reversed_empty_ranges` + error: lint `clippy::single_char_push_str` has been renamed to `clippy::single_char_add_str` --> tests/ui/rename.rs:98:9 | @@ -253,155 +253,161 @@ error: lint `clippy::cmp_nan` has been renamed to `invalid_nan_comparisons` LL | #![warn(clippy::cmp_nan)] | ^^^^^^^^^^^^^^^ help: use the new name: `invalid_nan_comparisons` -error: lint `clippy::drop_bounds` has been renamed to `drop_bounds` +error: lint `clippy::double_neg` has been renamed to `double_negations` --> tests/ui/rename.rs:107:9 | +LL | #![warn(clippy::double_neg)] + | ^^^^^^^^^^^^^^^^^^ help: use the new name: `double_negations` + +error: lint `clippy::drop_bounds` has been renamed to `drop_bounds` + --> tests/ui/rename.rs:108:9 + | LL | #![warn(clippy::drop_bounds)] | ^^^^^^^^^^^^^^^^^^^ help: use the new name: `drop_bounds` error: lint `clippy::drop_copy` has been renamed to `dropping_copy_types` - --> tests/ui/rename.rs:108:9 + --> tests/ui/rename.rs:109:9 | LL | #![warn(clippy::drop_copy)] | ^^^^^^^^^^^^^^^^^ help: use the new name: `dropping_copy_types` error: lint `clippy::drop_ref` has been renamed to `dropping_references` - --> tests/ui/rename.rs:109:9 + --> tests/ui/rename.rs:110:9 | LL | #![warn(clippy::drop_ref)] | ^^^^^^^^^^^^^^^^ help: use the new name: `dropping_references` +error: lint `clippy::fn_address_comparisons` has been renamed to `unpredictable_function_pointer_comparisons` + --> tests/ui/rename.rs:111:9 + | +LL | #![warn(clippy::fn_address_comparisons)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `unpredictable_function_pointer_comparisons` + error: lint `clippy::fn_null_check` has been renamed to `useless_ptr_null_checks` - --> tests/ui/rename.rs:110:9 + --> tests/ui/rename.rs:112:9 | LL | #![warn(clippy::fn_null_check)] | ^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `useless_ptr_null_checks` error: lint `clippy::for_loop_over_option` has been renamed to `for_loops_over_fallibles` - --> tests/ui/rename.rs:111:9 + --> tests/ui/rename.rs:113:9 | LL | #![warn(clippy::for_loop_over_option)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `for_loops_over_fallibles` error: lint `clippy::for_loop_over_result` has been renamed to `for_loops_over_fallibles` - --> tests/ui/rename.rs:112:9 + --> tests/ui/rename.rs:114:9 | LL | #![warn(clippy::for_loop_over_result)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `for_loops_over_fallibles` error: lint `clippy::for_loops_over_fallibles` has been renamed to `for_loops_over_fallibles` - --> tests/ui/rename.rs:113:9 + --> tests/ui/rename.rs:115:9 | LL | #![warn(clippy::for_loops_over_fallibles)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `for_loops_over_fallibles` error: lint `clippy::forget_copy` has been renamed to `forgetting_copy_types` - --> tests/ui/rename.rs:114:9 + --> tests/ui/rename.rs:116:9 | LL | #![warn(clippy::forget_copy)] | ^^^^^^^^^^^^^^^^^^^ help: use the new name: `forgetting_copy_types` error: lint `clippy::forget_ref` has been renamed to `forgetting_references` - --> tests/ui/rename.rs:115:9 + --> tests/ui/rename.rs:117:9 | LL | #![warn(clippy::forget_ref)] | ^^^^^^^^^^^^^^^^^^ help: use the new name: `forgetting_references` error: lint `clippy::into_iter_on_array` has been renamed to `array_into_iter` - --> tests/ui/rename.rs:116:9 + --> tests/ui/rename.rs:118:9 | LL | #![warn(clippy::into_iter_on_array)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `array_into_iter` error: lint `clippy::invalid_atomic_ordering` has been renamed to `invalid_atomic_ordering` - --> tests/ui/rename.rs:117:9 + --> tests/ui/rename.rs:119:9 | LL | #![warn(clippy::invalid_atomic_ordering)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `invalid_atomic_ordering` error: lint `clippy::invalid_ref` has been renamed to `invalid_value` - --> tests/ui/rename.rs:118:9 + --> tests/ui/rename.rs:120:9 | LL | #![warn(clippy::invalid_ref)] | ^^^^^^^^^^^^^^^^^^^ help: use the new name: `invalid_value` error: lint `clippy::invalid_utf8_in_unchecked` has been renamed to `invalid_from_utf8_unchecked` - --> tests/ui/rename.rs:119:9 + --> tests/ui/rename.rs:121:9 | LL | #![warn(clippy::invalid_utf8_in_unchecked)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `invalid_from_utf8_unchecked` error: lint `clippy::let_underscore_drop` has been renamed to `let_underscore_drop` - --> tests/ui/rename.rs:120:9 + --> tests/ui/rename.rs:122:9 | LL | #![warn(clippy::let_underscore_drop)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `let_underscore_drop` error: lint `clippy::maybe_misused_cfg` has been renamed to `unexpected_cfgs` - --> tests/ui/rename.rs:121:9 + --> tests/ui/rename.rs:123:9 | LL | #![warn(clippy::maybe_misused_cfg)] | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `unexpected_cfgs` error: lint `clippy::mem_discriminant_non_enum` has been renamed to `enum_intrinsics_non_enums` - --> tests/ui/rename.rs:122:9 + --> tests/ui/rename.rs:124:9 | LL | #![warn(clippy::mem_discriminant_non_enum)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `enum_intrinsics_non_enums` error: lint `clippy::mismatched_target_os` has been renamed to `unexpected_cfgs` - --> tests/ui/rename.rs:123:9 + --> tests/ui/rename.rs:125:9 | LL | #![warn(clippy::mismatched_target_os)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `unexpected_cfgs` error: lint `clippy::panic_params` has been renamed to `non_fmt_panics` - --> tests/ui/rename.rs:124:9 + --> tests/ui/rename.rs:126:9 | LL | #![warn(clippy::panic_params)] | ^^^^^^^^^^^^^^^^^^^^ help: use the new name: `non_fmt_panics` error: lint `clippy::positional_named_format_parameters` has been renamed to `named_arguments_used_positionally` - --> tests/ui/rename.rs:125:9 + --> tests/ui/rename.rs:127:9 | LL | #![warn(clippy::positional_named_format_parameters)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `named_arguments_used_positionally` error: lint `clippy::temporary_cstring_as_ptr` has been renamed to `dangling_pointers_from_temporaries` - --> tests/ui/rename.rs:126:9 + --> tests/ui/rename.rs:128:9 | LL | #![warn(clippy::temporary_cstring_as_ptr)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `dangling_pointers_from_temporaries` error: lint `clippy::undropped_manually_drops` has been renamed to `undropped_manually_drops` - --> tests/ui/rename.rs:127:9 + --> tests/ui/rename.rs:129:9 | LL | #![warn(clippy::undropped_manually_drops)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `undropped_manually_drops` error: lint `clippy::unknown_clippy_lints` has been renamed to `unknown_lints` - --> tests/ui/rename.rs:128:9 + --> tests/ui/rename.rs:130:9 | LL | #![warn(clippy::unknown_clippy_lints)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `unknown_lints` error: lint `clippy::unused_label` has been renamed to `unused_labels` - --> tests/ui/rename.rs:129:9 + --> tests/ui/rename.rs:131:9 | LL | #![warn(clippy::unused_label)] | ^^^^^^^^^^^^^^^^^^^^ help: use the new name: `unused_labels` error: lint `clippy::vtable_address_comparisons` has been renamed to `ambiguous_wide_pointer_comparisons` - --> tests/ui/rename.rs:130:9 + --> tests/ui/rename.rs:132:9 | LL | #![warn(clippy::vtable_address_comparisons)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `ambiguous_wide_pointer_comparisons` -error: lint `clippy::reverse_range_loop` has been renamed to `clippy::reversed_empty_ranges` - --> tests/ui/rename.rs:131:9 - | -LL | #![warn(clippy::reverse_range_loop)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::reversed_empty_ranges` - -error: aborting due to 67 previous errors +error: aborting due to 68 previous errors From c1dcbebd0b4f721cead9d0f7ad63b88d8effed43 Mon Sep 17 00:00:00 2001 From: Kalle Wachsmuth Date: Sun, 1 Sep 2024 19:22:35 +0200 Subject: [PATCH 55/81] implement lint `double_negations` --- compiler/rustc_lint/messages.ftl | 5 ++ compiler/rustc_lint/src/builtin.rs | 75 ++++++++++++++++++---- compiler/rustc_lint/src/lib.rs | 1 + compiler/rustc_lint/src/lints.rs | 18 ++++++ tests/ui/lint/lint-double-negations.rs | 9 +++ tests/ui/lint/lint-double-negations.stderr | 42 ++++++++++++ tests/ui/lint/lint-type-overflow2.rs | 1 + tests/ui/lint/lint-type-overflow2.stderr | 24 +++++-- 8 files changed, 159 insertions(+), 16 deletions(-) create mode 100644 tests/ui/lint/lint-double-negations.rs create mode 100644 tests/ui/lint/lint-double-negations.stderr diff --git a/compiler/rustc_lint/messages.ftl b/compiler/rustc_lint/messages.ftl index 0c1bd08474fc..55c6a122d35d 100644 --- a/compiler/rustc_lint/messages.ftl +++ b/compiler/rustc_lint/messages.ftl @@ -76,6 +76,11 @@ lint_builtin_deprecated_attr_link = use of deprecated attribute `{$name}`: {$rea lint_builtin_deref_nullptr = dereferencing a null pointer .label = this code causes undefined behavior when executed +lint_builtin_double_negations = use of a double negation + .note = the prefix `--` could be misinterpreted as a decrement operator which exists in other languages + .note_decrement = use `-= 1` if you meant to decrement the value + .add_parens_suggestion = add parentheses for clarity + lint_builtin_ellipsis_inclusive_range_patterns = `...` range patterns are deprecated .suggestion = use `..=` for an inclusive range diff --git a/compiler/rustc_lint/src/builtin.rs b/compiler/rustc_lint/src/builtin.rs index 3da9ef3ff7c6..c03de687a338 100644 --- a/compiler/rustc_lint/src/builtin.rs +++ b/compiler/rustc_lint/src/builtin.rs @@ -49,16 +49,16 @@ use rustc_trait_selection::traits::{self}; use crate::errors::BuiltinEllipsisInclusiveRangePatterns; use crate::lints::{ BuiltinAnonymousParams, BuiltinConstNoMangle, BuiltinDeprecatedAttrLink, - BuiltinDeprecatedAttrLinkSuggestion, BuiltinDerefNullptr, - BuiltinEllipsisInclusiveRangePatternsLint, BuiltinExplicitOutlives, - BuiltinExplicitOutlivesSuggestion, BuiltinFeatureIssueNote, BuiltinIncompleteFeatures, - BuiltinIncompleteFeaturesHelp, BuiltinInternalFeatures, BuiltinKeywordIdents, - BuiltinMissingCopyImpl, BuiltinMissingDebugImpl, BuiltinMissingDoc, BuiltinMutablesTransmutes, - BuiltinNoMangleGeneric, BuiltinNonShorthandFieldPatterns, BuiltinSpecialModuleNameUsed, - BuiltinTrivialBounds, BuiltinTypeAliasBounds, BuiltinUngatedAsyncFnTrackCaller, - BuiltinUnpermittedTypeInit, BuiltinUnpermittedTypeInitSub, BuiltinUnreachablePub, - BuiltinUnsafe, BuiltinUnstableFeatures, BuiltinUnusedDocComment, BuiltinUnusedDocCommentSub, - BuiltinWhileTrue, InvalidAsmLabel, + BuiltinDeprecatedAttrLinkSuggestion, BuiltinDerefNullptr, BuiltinDoubleNegations, + BuiltinDoubleNegationsAddParens, BuiltinEllipsisInclusiveRangePatternsLint, + BuiltinExplicitOutlives, BuiltinExplicitOutlivesSuggestion, BuiltinFeatureIssueNote, + BuiltinIncompleteFeatures, BuiltinIncompleteFeaturesHelp, BuiltinInternalFeatures, + BuiltinKeywordIdents, BuiltinMissingCopyImpl, BuiltinMissingDebugImpl, BuiltinMissingDoc, + BuiltinMutablesTransmutes, BuiltinNoMangleGeneric, BuiltinNonShorthandFieldPatterns, + BuiltinSpecialModuleNameUsed, BuiltinTrivialBounds, BuiltinTypeAliasBounds, + BuiltinUngatedAsyncFnTrackCaller, BuiltinUnpermittedTypeInit, BuiltinUnpermittedTypeInitSub, + BuiltinUnreachablePub, BuiltinUnsafe, BuiltinUnstableFeatures, BuiltinUnusedDocComment, + BuiltinUnusedDocCommentSub, BuiltinWhileTrue, InvalidAsmLabel, }; use crate::nonstandard_style::{MethodLateContext, method_context}; use crate::{ @@ -1568,6 +1568,58 @@ impl<'tcx> LateLintPass<'tcx> for TrivialConstraints { } } +declare_lint! { + /// The `double_negations` lint detects expressions of the form `--x`. + /// + /// ### Example + /// + /// ```rust + /// fn main() { + /// let x = 1; + /// let _b = --x; + /// } + /// ``` + /// + /// {{produces}} + /// + /// ### Explanation + /// + /// Negating something twice is usually the same as not negating it at all. + /// However, a double negation in Rust can easily be confused with the + /// prefix decrement operator that exists in many languages derived from C. + /// Use `-(-x)` if you really wanted to negate the value twice. + /// + /// To decrement a value, use `x -= 1` instead. + pub DOUBLE_NEGATIONS, + Warn, + "detects expressions of the form `--x`" +} + +declare_lint_pass!( + /// Lint for expressions of the form `--x` that can be confused with C's + /// prefix decrement operator. + DoubleNegations => [DOUBLE_NEGATIONS] +); + +impl EarlyLintPass for DoubleNegations { + #[inline] + fn check_expr(&mut self, cx: &EarlyContext<'_>, expr: &ast::Expr) { + // only lint on the innermost `--` in a chain of `-` operators, + // even if there are 3 or more negations + if let ExprKind::Unary(UnOp::Neg, ref inner) = expr.kind + && let ExprKind::Unary(UnOp::Neg, ref inner2) = inner.kind + && !matches!(inner2.kind, ExprKind::Unary(UnOp::Neg, _)) + { + cx.emit_span_lint(DOUBLE_NEGATIONS, expr.span, BuiltinDoubleNegations { + add_parens: BuiltinDoubleNegationsAddParens { + start_span: inner.span.shrink_to_lo(), + end_span: inner.span.shrink_to_hi(), + }, + }); + } + } +} + declare_lint_pass!( /// Does nothing as a lint pass, but registers some `Lint`s /// which are used by other parts of the compiler. @@ -1586,7 +1638,8 @@ declare_lint_pass!( UNSTABLE_FEATURES, UNREACHABLE_PUB, TYPE_ALIAS_BOUNDS, - TRIVIAL_BOUNDS + TRIVIAL_BOUNDS, + DOUBLE_NEGATIONS ] ); diff --git a/compiler/rustc_lint/src/lib.rs b/compiler/rustc_lint/src/lib.rs index 1465c2cff7bc..83a168c3f446 100644 --- a/compiler/rustc_lint/src/lib.rs +++ b/compiler/rustc_lint/src/lib.rs @@ -181,6 +181,7 @@ early_lint_methods!( UnusedDocComment: UnusedDocComment, Expr2024: Expr2024, Precedence: Precedence, + DoubleNegations: DoubleNegations, ] ] ); diff --git a/compiler/rustc_lint/src/lints.rs b/compiler/rustc_lint/src/lints.rs index 3163bc8a300a..677fc86a2351 100644 --- a/compiler/rustc_lint/src/lints.rs +++ b/compiler/rustc_lint/src/lints.rs @@ -331,6 +331,24 @@ pub(crate) struct BuiltinTrivialBounds<'a> { pub predicate: Clause<'a>, } +#[derive(LintDiagnostic)] +#[diag(lint_builtin_double_negations)] +#[note(lint_note)] +#[note(lint_note_decrement)] +pub(crate) struct BuiltinDoubleNegations { + #[subdiagnostic] + pub add_parens: BuiltinDoubleNegationsAddParens, +} + +#[derive(Subdiagnostic)] +#[multipart_suggestion(lint_add_parens_suggestion, applicability = "maybe-incorrect")] +pub(crate) struct BuiltinDoubleNegationsAddParens { + #[suggestion_part(code = "(")] + pub start_span: Span, + #[suggestion_part(code = ")")] + pub end_span: Span, +} + #[derive(LintDiagnostic)] pub(crate) enum BuiltinEllipsisInclusiveRangePatternsLint { #[diag(lint_builtin_ellipsis_inclusive_range_patterns)] diff --git a/tests/ui/lint/lint-double-negations.rs b/tests/ui/lint/lint-double-negations.rs new file mode 100644 index 000000000000..43e61dd7c132 --- /dev/null +++ b/tests/ui/lint/lint-double-negations.rs @@ -0,0 +1,9 @@ +//@ check-pass +fn main() { + let x = 1; + -x; + -(-x); + --x; //~ WARN use of a double negation + ---x; //~ WARN use of a double negation + let _y = --(-x); //~ WARN use of a double negation +} diff --git a/tests/ui/lint/lint-double-negations.stderr b/tests/ui/lint/lint-double-negations.stderr new file mode 100644 index 000000000000..9367f74be546 --- /dev/null +++ b/tests/ui/lint/lint-double-negations.stderr @@ -0,0 +1,42 @@ +warning: use of a double negation + --> $DIR/lint-double-negations.rs:6:5 + | +LL | --x; + | ^^^ + | + = note: the prefix `--` could be misinterpreted as a decrement operator which exists in other languages + = note: use `-= 1` if you meant to decrement the value + = note: `#[warn(double_negations)]` on by default +help: add parentheses for clarity + | +LL | -(-x); + | + + + +warning: use of a double negation + --> $DIR/lint-double-negations.rs:7:6 + | +LL | ---x; + | ^^^ + | + = note: the prefix `--` could be misinterpreted as a decrement operator which exists in other languages + = note: use `-= 1` if you meant to decrement the value +help: add parentheses for clarity + | +LL | --(-x); + | + + + +warning: use of a double negation + --> $DIR/lint-double-negations.rs:8:14 + | +LL | let _y = --(-x); + | ^^^^^^ + | + = note: the prefix `--` could be misinterpreted as a decrement operator which exists in other languages + = note: use `-= 1` if you meant to decrement the value +help: add parentheses for clarity + | +LL | let _y = -(-(-x)); + | + + + +warning: 3 warnings emitted + diff --git a/tests/ui/lint/lint-type-overflow2.rs b/tests/ui/lint/lint-type-overflow2.rs index f007b45b8479..ac7420326c89 100644 --- a/tests/ui/lint/lint-type-overflow2.rs +++ b/tests/ui/lint/lint-type-overflow2.rs @@ -4,6 +4,7 @@ fn main() { let x2: i8 = --128; //~ ERROR literal out of range for `i8` + //~| WARN use of a double negation let x = -3.40282357e+38_f32; //~ ERROR literal out of range for `f32` let x = 3.40282357e+38_f32; //~ ERROR literal out of range for `f32` diff --git a/tests/ui/lint/lint-type-overflow2.stderr b/tests/ui/lint/lint-type-overflow2.stderr index eb593d062f21..2cfb18e9fe92 100644 --- a/tests/ui/lint/lint-type-overflow2.stderr +++ b/tests/ui/lint/lint-type-overflow2.stderr @@ -1,3 +1,17 @@ +warning: use of a double negation + --> $DIR/lint-type-overflow2.rs:6:18 + | +LL | let x2: i8 = --128; + | ^^^^^ + | + = note: the prefix `--` could be misinterpreted as a decrement operator which exists in other languages + = note: use `-= 1` if you meant to decrement the value + = note: `#[warn(double_negations)]` on by default +help: add parentheses for clarity + | +LL | let x2: i8 = -(-128); + | + + + error: literal out of range for `i8` --> $DIR/lint-type-overflow2.rs:6:20 | @@ -13,7 +27,7 @@ LL | #![deny(overflowing_literals)] | ^^^^^^^^^^^^^^^^^^^^ error: literal out of range for `f32` - --> $DIR/lint-type-overflow2.rs:8:14 + --> $DIR/lint-type-overflow2.rs:9:14 | LL | let x = -3.40282357e+38_f32; | ^^^^^^^^^^^^^^^^^^ @@ -21,7 +35,7 @@ LL | let x = -3.40282357e+38_f32; = note: the literal `3.40282357e+38_f32` does not fit into the type `f32` and will be converted to `f32::INFINITY` error: literal out of range for `f32` - --> $DIR/lint-type-overflow2.rs:9:14 + --> $DIR/lint-type-overflow2.rs:10:14 | LL | let x = 3.40282357e+38_f32; | ^^^^^^^^^^^^^^^^^^ @@ -29,7 +43,7 @@ LL | let x = 3.40282357e+38_f32; = note: the literal `3.40282357e+38_f32` does not fit into the type `f32` and will be converted to `f32::INFINITY` error: literal out of range for `f64` - --> $DIR/lint-type-overflow2.rs:10:14 + --> $DIR/lint-type-overflow2.rs:11:14 | LL | let x = -1.7976931348623159e+308_f64; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -37,12 +51,12 @@ LL | let x = -1.7976931348623159e+308_f64; = note: the literal `1.7976931348623159e+308_f64` does not fit into the type `f64` and will be converted to `f64::INFINITY` error: literal out of range for `f64` - --> $DIR/lint-type-overflow2.rs:11:14 + --> $DIR/lint-type-overflow2.rs:12:14 | LL | let x = 1.7976931348623159e+308_f64; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: the literal `1.7976931348623159e+308_f64` does not fit into the type `f64` and will be converted to `f64::INFINITY` -error: aborting due to 5 previous errors +error: aborting due to 5 previous errors; 1 warning emitted From 68e983fcf7226c2e17b1dd568e566b02989efec5 Mon Sep 17 00:00:00 2001 From: Tobias Bucher Date: Fri, 17 Jan 2025 16:55:10 +0100 Subject: [PATCH 56/81] Move `std::io::pipe` code into its own file --- library/std/src/io/mod.rs | 258 +------------------------------ library/std/src/io/pipe.rs | 256 ++++++++++++++++++++++++++++++ library/std/src/io/pipe/tests.rs | 18 +++ library/std/src/io/tests.rs | 17 -- 4 files changed, 277 insertions(+), 272 deletions(-) create mode 100644 library/std/src/io/pipe.rs create mode 100644 library/std/src/io/pipe/tests.rs diff --git a/library/std/src/io/mod.rs b/library/std/src/io/mod.rs index 1fa13e95e687..cfd03b8e3d6d 100644 --- a/library/std/src/io/mod.rs +++ b/library/std/src/io/mod.rs @@ -310,6 +310,8 @@ pub use self::error::RawOsError; pub use self::error::SimpleMessage; #[unstable(feature = "io_const_error", issue = "133448")] pub use self::error::const_error; +#[unstable(feature = "anonymous_pipe", issue = "127154")] +pub use self::pipe::{PipeReader, PipeWriter, pipe}; #[stable(feature = "is_terminal", since = "1.70.0")] pub use self::stdio::IsTerminal; pub(crate) use self::stdio::attempt_print_to_stderr; @@ -330,7 +332,6 @@ pub use self::{ }; use crate::mem::take; use crate::ops::{Deref, DerefMut}; -use crate::sys::anonymous_pipe::{AnonPipe, pipe as pipe_inner}; use crate::{cmp, fmt, slice, str, sys}; mod buffered; @@ -338,6 +339,7 @@ pub(crate) mod copy; mod cursor; mod error; mod impls; +mod pipe; pub mod prelude; mod stdio; mod util; @@ -3251,257 +3253,3 @@ impl Iterator for Lines { } } } - -/// Create an anonymous pipe that is close-on-exec and blocking. -/// -/// # Behavior -/// -/// A pipe is a one-way data channel provided by the OS, which works across processes. A pipe is -/// typically used to communicate between two or more separate processes, as there are better, -/// faster ways to communicate within a single process. -/// -/// In particular: -/// -/// * A read on a [`PipeReader`] blocks until the pipe is non-empty. -/// * A write on a [`PipeWriter`] blocks when the pipe is full. -/// * When all copies of a [`PipeWriter`] are closed, a read on the corresponding [`PipeReader`] -/// returns EOF. -/// * [`PipeWriter`] can be shared, and multiple processes or threads can write to it at once, but -/// writes (above a target-specific threshold) may have their data interleaved. -/// * [`PipeReader`] can be shared, and multiple processes or threads can read it at once. Any -/// given byte will only get consumed by one reader. There are no guarantees about data -/// interleaving. -/// * Portable applications cannot assume any atomicity of messages larger than a single byte. -/// -/// # Capacity -/// -/// Pipe capacity is platform dependent. To quote the Linux [man page]: -/// -/// > Different implementations have different limits for the pipe capacity. Applications should -/// > not rely on a particular capacity: an application should be designed so that a reading process -/// > consumes data as soon as it is available, so that a writing process does not remain blocked. -/// -/// # Examples -/// -/// ```no_run -/// #![feature(anonymous_pipe)] -/// # #[cfg(miri)] fn main() {} -/// # #[cfg(not(miri))] -/// # fn main() -> std::io::Result<()> { -/// # use std::process::Command; -/// # use std::io::{Read, Write}; -/// let (ping_rx, mut ping_tx) = std::io::pipe()?; -/// let (mut pong_rx, pong_tx) = std::io::pipe()?; -/// -/// // Spawn a process that echoes its input. -/// let mut echo_server = Command::new("cat").stdin(ping_rx).stdout(pong_tx).spawn()?; -/// -/// ping_tx.write_all(b"hello")?; -/// // Close to unblock echo_server's reader. -/// drop(ping_tx); -/// -/// let mut buf = String::new(); -/// // Block until echo_server's writer is closed. -/// pong_rx.read_to_string(&mut buf)?; -/// assert_eq!(&buf, "hello"); -/// -/// echo_server.wait()?; -/// # Ok(()) -/// # } -/// ``` -/// [man page]: https://man7.org/linux/man-pages/man7/pipe.7.html -#[unstable(feature = "anonymous_pipe", issue = "127154")] -#[inline] -pub fn pipe() -> Result<(PipeReader, PipeWriter)> { - pipe_inner().map(|(reader, writer)| (PipeReader(reader), PipeWriter(writer))) -} - -/// Read end of an anonymous pipe. -#[unstable(feature = "anonymous_pipe", issue = "127154")] -#[derive(Debug)] -pub struct PipeReader(pub(crate) AnonPipe); - -/// Write end of an anonymous pipe. -#[unstable(feature = "anonymous_pipe", issue = "127154")] -#[derive(Debug)] -pub struct PipeWriter(pub(crate) AnonPipe); - -impl PipeReader { - /// Create a new [`PipeReader`] instance that shares the same underlying file description. - /// - /// # Examples - /// - /// ```no_run - /// #![feature(anonymous_pipe)] - /// # #[cfg(miri)] fn main() {} - /// # #[cfg(not(miri))] - /// # fn main() -> std::io::Result<()> { - /// # use std::fs; - /// # use std::io::Write; - /// # use std::process::Command; - /// const NUM_SLOT: u8 = 2; - /// const NUM_PROC: u8 = 5; - /// const OUTPUT: &str = "work.txt"; - /// - /// let mut jobs = vec![]; - /// let (reader, mut writer) = std::io::pipe()?; - /// - /// // Write NUM_SLOT characters the pipe. - /// writer.write_all(&[b'|'; NUM_SLOT as usize])?; - /// - /// // Spawn several processes that read a character from the pipe, do some work, then - /// // write back to the pipe. When the pipe is empty, the processes block, so only - /// // NUM_SLOT processes can be working at any given time. - /// for _ in 0..NUM_PROC { - /// jobs.push( - /// Command::new("bash") - /// .args(["-c", - /// &format!( - /// "read -n 1\n\ - /// echo -n 'x' >> '{OUTPUT}'\n\ - /// echo -n '|'", - /// ), - /// ]) - /// .stdin(reader.try_clone()?) - /// .stdout(writer.try_clone()?) - /// .spawn()?, - /// ); - /// } - /// - /// // Wait for all jobs to finish. - /// for mut job in jobs { - /// job.wait()?; - /// } - /// - /// // Check our work and clean up. - /// let xs = fs::read_to_string(OUTPUT)?; - /// fs::remove_file(OUTPUT)?; - /// assert_eq!(xs, "x".repeat(NUM_PROC.into())); - /// # Ok(()) - /// # } - /// ``` - #[unstable(feature = "anonymous_pipe", issue = "127154")] - pub fn try_clone(&self) -> Result { - self.0.try_clone().map(Self) - } -} - -impl PipeWriter { - /// Create a new [`PipeWriter`] instance that shares the same underlying file description. - /// - /// # Examples - /// - /// ```no_run - /// #![feature(anonymous_pipe)] - /// # #[cfg(miri)] fn main() {} - /// # #[cfg(not(miri))] - /// # fn main() -> std::io::Result<()> { - /// # use std::process::Command; - /// # use std::io::Read; - /// let (mut reader, writer) = std::io::pipe()?; - /// - /// // Spawn a process that writes to stdout and stderr. - /// let mut peer = Command::new("bash") - /// .args([ - /// "-c", - /// "echo -n foo\n\ - /// echo -n bar >&2" - /// ]) - /// .stdout(writer.try_clone()?) - /// .stderr(writer) - /// .spawn()?; - /// - /// // Read and check the result. - /// let mut msg = String::new(); - /// reader.read_to_string(&mut msg)?; - /// assert_eq!(&msg, "foobar"); - /// - /// peer.wait()?; - /// # Ok(()) - /// # } - /// ``` - #[unstable(feature = "anonymous_pipe", issue = "127154")] - pub fn try_clone(&self) -> Result { - self.0.try_clone().map(Self) - } -} - -#[unstable(feature = "anonymous_pipe", issue = "127154")] -impl Read for &PipeReader { - fn read(&mut self, buf: &mut [u8]) -> Result { - self.0.read(buf) - } - fn read_vectored(&mut self, bufs: &mut [IoSliceMut<'_>]) -> Result { - self.0.read_vectored(bufs) - } - #[inline] - fn is_read_vectored(&self) -> bool { - self.0.is_read_vectored() - } - fn read_to_end(&mut self, buf: &mut Vec) -> Result { - self.0.read_to_end(buf) - } - fn read_buf(&mut self, buf: BorrowedCursor<'_>) -> Result<()> { - self.0.read_buf(buf) - } -} - -#[unstable(feature = "anonymous_pipe", issue = "127154")] -impl Read for PipeReader { - fn read(&mut self, buf: &mut [u8]) -> Result { - self.0.read(buf) - } - fn read_vectored(&mut self, bufs: &mut [IoSliceMut<'_>]) -> Result { - self.0.read_vectored(bufs) - } - #[inline] - fn is_read_vectored(&self) -> bool { - self.0.is_read_vectored() - } - fn read_to_end(&mut self, buf: &mut Vec) -> Result { - self.0.read_to_end(buf) - } - fn read_buf(&mut self, buf: BorrowedCursor<'_>) -> Result<()> { - self.0.read_buf(buf) - } -} - -#[unstable(feature = "anonymous_pipe", issue = "127154")] -impl Write for &PipeWriter { - fn write(&mut self, buf: &[u8]) -> Result { - self.0.write(buf) - } - #[inline] - fn flush(&mut self) -> Result<()> { - Ok(()) - } - - fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> Result { - self.0.write_vectored(bufs) - } - - #[inline] - fn is_write_vectored(&self) -> bool { - self.0.is_write_vectored() - } -} - -#[unstable(feature = "anonymous_pipe", issue = "127154")] -impl Write for PipeWriter { - fn write(&mut self, buf: &[u8]) -> Result { - self.0.write(buf) - } - #[inline] - fn flush(&mut self) -> Result<()> { - Ok(()) - } - - fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> Result { - self.0.write_vectored(bufs) - } - - #[inline] - fn is_write_vectored(&self) -> bool { - self.0.is_write_vectored() - } -} diff --git a/library/std/src/io/pipe.rs b/library/std/src/io/pipe.rs new file mode 100644 index 000000000000..cd33294b2710 --- /dev/null +++ b/library/std/src/io/pipe.rs @@ -0,0 +1,256 @@ +use crate::io; +use crate::sys::anonymous_pipe::{AnonPipe, pipe as pipe_inner}; + +/// Create an anonymous pipe that is close-on-exec and blocking. +/// +/// # Behavior +/// +/// A pipe is a one-way data channel provided by the OS, which works across processes. A pipe is +/// typically used to communicate between two or more separate processes, as there are better, +/// faster ways to communicate within a single process. +/// +/// In particular: +/// +/// * A read on a [`PipeReader`] blocks until the pipe is non-empty. +/// * A write on a [`PipeWriter`] blocks when the pipe is full. +/// * When all copies of a [`PipeWriter`] are closed, a read on the corresponding [`PipeReader`] +/// returns EOF. +/// * [`PipeWriter`] can be shared, and multiple processes or threads can write to it at once, but +/// writes (above a target-specific threshold) may have their data interleaved. +/// * [`PipeReader`] can be shared, and multiple processes or threads can read it at once. Any +/// given byte will only get consumed by one reader. There are no guarantees about data +/// interleaving. +/// * Portable applications cannot assume any atomicity of messages larger than a single byte. +/// +/// # Capacity +/// +/// Pipe capacity is platform dependent. To quote the Linux [man page]: +/// +/// > Different implementations have different limits for the pipe capacity. Applications should +/// > not rely on a particular capacity: an application should be designed so that a reading process +/// > consumes data as soon as it is available, so that a writing process does not remain blocked. +/// +/// # Examples +/// +/// ```no_run +/// #![feature(anonymous_pipe)] +/// # #[cfg(miri)] fn main() {} +/// # #[cfg(not(miri))] +/// # fn main() -> std::io::Result<()> { +/// # use std::process::Command; +/// # use std::io::{Read, Write}; +/// let (ping_rx, mut ping_tx) = std::io::pipe()?; +/// let (mut pong_rx, pong_tx) = std::io::pipe()?; +/// +/// // Spawn a process that echoes its input. +/// let mut echo_server = Command::new("cat").stdin(ping_rx).stdout(pong_tx).spawn()?; +/// +/// ping_tx.write_all(b"hello")?; +/// // Close to unblock echo_server's reader. +/// drop(ping_tx); +/// +/// let mut buf = String::new(); +/// // Block until echo_server's writer is closed. +/// pong_rx.read_to_string(&mut buf)?; +/// assert_eq!(&buf, "hello"); +/// +/// echo_server.wait()?; +/// # Ok(()) +/// # } +/// ``` +/// [man page]: https://man7.org/linux/man-pages/man7/pipe.7.html +#[unstable(feature = "anonymous_pipe", issue = "127154")] +#[inline] +pub fn pipe() -> io::Result<(PipeReader, PipeWriter)> { + pipe_inner().map(|(reader, writer)| (PipeReader(reader), PipeWriter(writer))) +} + +/// Read end of an anonymous pipe. +#[unstable(feature = "anonymous_pipe", issue = "127154")] +#[derive(Debug)] +pub struct PipeReader(pub(crate) AnonPipe); + +/// Write end of an anonymous pipe. +#[unstable(feature = "anonymous_pipe", issue = "127154")] +#[derive(Debug)] +pub struct PipeWriter(pub(crate) AnonPipe); + +impl PipeReader { + /// Create a new [`PipeReader`] instance that shares the same underlying file description. + /// + /// # Examples + /// + /// ```no_run + /// #![feature(anonymous_pipe)] + /// # #[cfg(miri)] fn main() {} + /// # #[cfg(not(miri))] + /// # fn main() -> std::io::Result<()> { + /// # use std::fs; + /// # use std::io::Write; + /// # use std::process::Command; + /// const NUM_SLOT: u8 = 2; + /// const NUM_PROC: u8 = 5; + /// const OUTPUT: &str = "work.txt"; + /// + /// let mut jobs = vec![]; + /// let (reader, mut writer) = std::io::pipe()?; + /// + /// // Write NUM_SLOT characters the pipe. + /// writer.write_all(&[b'|'; NUM_SLOT as usize])?; + /// + /// // Spawn several processes that read a character from the pipe, do some work, then + /// // write back to the pipe. When the pipe is empty, the processes block, so only + /// // NUM_SLOT processes can be working at any given time. + /// for _ in 0..NUM_PROC { + /// jobs.push( + /// Command::new("bash") + /// .args(["-c", + /// &format!( + /// "read -n 1\n\ + /// echo -n 'x' >> '{OUTPUT}'\n\ + /// echo -n '|'", + /// ), + /// ]) + /// .stdin(reader.try_clone()?) + /// .stdout(writer.try_clone()?) + /// .spawn()?, + /// ); + /// } + /// + /// // Wait for all jobs to finish. + /// for mut job in jobs { + /// job.wait()?; + /// } + /// + /// // Check our work and clean up. + /// let xs = fs::read_to_string(OUTPUT)?; + /// fs::remove_file(OUTPUT)?; + /// assert_eq!(xs, "x".repeat(NUM_PROC.into())); + /// # Ok(()) + /// # } + /// ``` + #[unstable(feature = "anonymous_pipe", issue = "127154")] + pub fn try_clone(&self) -> io::Result { + self.0.try_clone().map(Self) + } +} + +impl PipeWriter { + /// Create a new [`PipeWriter`] instance that shares the same underlying file description. + /// + /// # Examples + /// + /// ```no_run + /// #![feature(anonymous_pipe)] + /// # #[cfg(miri)] fn main() {} + /// # #[cfg(not(miri))] + /// # fn main() -> std::io::Result<()> { + /// # use std::process::Command; + /// # use std::io::Read; + /// let (mut reader, writer) = std::io::pipe()?; + /// + /// // Spawn a process that writes to stdout and stderr. + /// let mut peer = Command::new("bash") + /// .args([ + /// "-c", + /// "echo -n foo\n\ + /// echo -n bar >&2" + /// ]) + /// .stdout(writer.try_clone()?) + /// .stderr(writer) + /// .spawn()?; + /// + /// // Read and check the result. + /// let mut msg = String::new(); + /// reader.read_to_string(&mut msg)?; + /// assert_eq!(&msg, "foobar"); + /// + /// peer.wait()?; + /// # Ok(()) + /// # } + /// ``` + #[unstable(feature = "anonymous_pipe", issue = "127154")] + pub fn try_clone(&self) -> io::Result { + self.0.try_clone().map(Self) + } +} + +#[unstable(feature = "anonymous_pipe", issue = "127154")] +impl io::Read for &PipeReader { + fn read(&mut self, buf: &mut [u8]) -> io::Result { + self.0.read(buf) + } + fn read_vectored(&mut self, bufs: &mut [io::IoSliceMut<'_>]) -> io::Result { + self.0.read_vectored(bufs) + } + #[inline] + fn is_read_vectored(&self) -> bool { + self.0.is_read_vectored() + } + fn read_to_end(&mut self, buf: &mut Vec) -> io::Result { + self.0.read_to_end(buf) + } + fn read_buf(&mut self, buf: io::BorrowedCursor<'_>) -> io::Result<()> { + self.0.read_buf(buf) + } +} + +#[unstable(feature = "anonymous_pipe", issue = "127154")] +impl io::Read for PipeReader { + fn read(&mut self, buf: &mut [u8]) -> io::Result { + self.0.read(buf) + } + fn read_vectored(&mut self, bufs: &mut [io::IoSliceMut<'_>]) -> io::Result { + self.0.read_vectored(bufs) + } + #[inline] + fn is_read_vectored(&self) -> bool { + self.0.is_read_vectored() + } + fn read_to_end(&mut self, buf: &mut Vec) -> io::Result { + self.0.read_to_end(buf) + } + fn read_buf(&mut self, buf: io::BorrowedCursor<'_>) -> io::Result<()> { + self.0.read_buf(buf) + } +} + +#[unstable(feature = "anonymous_pipe", issue = "127154")] +impl io::Write for &PipeWriter { + fn write(&mut self, buf: &[u8]) -> io::Result { + self.0.write(buf) + } + #[inline] + fn flush(&mut self) -> io::Result<()> { + Ok(()) + } + + fn write_vectored(&mut self, bufs: &[io::IoSlice<'_>]) -> io::Result { + self.0.write_vectored(bufs) + } + + #[inline] + fn is_write_vectored(&self) -> bool { + self.0.is_write_vectored() + } +} + +#[unstable(feature = "anonymous_pipe", issue = "127154")] +impl io::Write for PipeWriter { + fn write(&mut self, buf: &[u8]) -> io::Result { + self.0.write(buf) + } + #[inline] + fn flush(&mut self) -> io::Result<()> { + Ok(()) + } + + fn write_vectored(&mut self, bufs: &[io::IoSlice<'_>]) -> io::Result { + self.0.write_vectored(bufs) + } + + #[inline] + fn is_write_vectored(&self) -> bool { + self.0.is_write_vectored() + } +} diff --git a/library/std/src/io/pipe/tests.rs b/library/std/src/io/pipe/tests.rs new file mode 100644 index 000000000000..c1f3f192ca2d --- /dev/null +++ b/library/std/src/io/pipe/tests.rs @@ -0,0 +1,18 @@ +use crate::io::{Read, Write, pipe}; + +#[test] +#[cfg(all(windows, unix, not(miri)))] +fn pipe_creation_clone_and_rw() { + let (rx, tx) = pipe().unwrap(); + + tx.try_clone().unwrap().write_all(b"12345").unwrap(); + drop(tx); + + let mut rx2 = rx.try_clone().unwrap(); + drop(rx); + + let mut s = String::new(); + rx2.read_to_string(&mut s).unwrap(); + drop(rx2); + assert_eq!(s, "12345"); +} diff --git a/library/std/src/io/tests.rs b/library/std/src/io/tests.rs index 226cc6011bca..f64f034cce77 100644 --- a/library/std/src/io/tests.rs +++ b/library/std/src/io/tests.rs @@ -821,20 +821,3 @@ fn try_oom_error() { let io_err = io::Error::from(reserve_err); assert_eq!(io::ErrorKind::OutOfMemory, io_err.kind()); } - -#[test] -#[cfg(all(windows, unix, not(miri)))] -fn pipe_creation_clone_and_rw() { - let (rx, tx) = std::io::pipe().unwrap(); - - tx.try_clone().unwrap().write_all(b"12345").unwrap(); - drop(tx); - - let mut rx2 = rx.try_clone().unwrap(); - drop(rx); - - let mut s = String::new(); - rx2.read_to_string(&mut s).unwrap(); - drop(rx2); - assert_eq!(s, "12345"); -} From ad28cbb423b5ab203a502ecee30d630e54ea3498 Mon Sep 17 00:00:00 2001 From: Tobias Bucher Date: Fri, 17 Jan 2025 17:11:08 +0100 Subject: [PATCH 57/81] Update `std::io::{pipe, PipeReader, PipeWriter}` docs the new location Also create a section "Platform-specific behavior", don't hide required imports for code examples. --- library/std/src/io/pipe.rs | 36 ++++++++++++++++++++---------------- 1 file changed, 20 insertions(+), 16 deletions(-) diff --git a/library/std/src/io/pipe.rs b/library/std/src/io/pipe.rs index cd33294b2710..266c7bc96389 100644 --- a/library/std/src/io/pipe.rs +++ b/library/std/src/io/pipe.rs @@ -1,7 +1,7 @@ use crate::io; use crate::sys::anonymous_pipe::{AnonPipe, pipe as pipe_inner}; -/// Create an anonymous pipe that is close-on-exec and blocking. +/// Create an anonymous pipe. /// /// # Behavior /// @@ -22,6 +22,13 @@ use crate::sys::anonymous_pipe::{AnonPipe, pipe as pipe_inner}; /// interleaving. /// * Portable applications cannot assume any atomicity of messages larger than a single byte. /// +/// # Platform-specific behavior +/// +/// This function currently corresponds to the `pipe` function on Unix and the +/// `CreatePipe` function on Windows. +/// +/// Note that this [may change in the future][changes]. +/// /// # Capacity /// /// Pipe capacity is platform dependent. To quote the Linux [man page]: @@ -37,10 +44,10 @@ use crate::sys::anonymous_pipe::{AnonPipe, pipe as pipe_inner}; /// # #[cfg(miri)] fn main() {} /// # #[cfg(not(miri))] /// # fn main() -> std::io::Result<()> { -/// # use std::process::Command; -/// # use std::io::{Read, Write}; -/// let (ping_rx, mut ping_tx) = std::io::pipe()?; -/// let (mut pong_rx, pong_tx) = std::io::pipe()?; +/// use std::process::Command; +/// use std::io::{pipe, Read, Write}; +/// let (ping_rx, mut ping_tx) = pipe()?; +/// let (mut pong_rx, pong_tx) = pipe()?; /// /// // Spawn a process that echoes its input. /// let mut echo_server = Command::new("cat").stdin(ping_rx).stdout(pong_tx).spawn()?; @@ -58,6 +65,7 @@ use crate::sys::anonymous_pipe::{AnonPipe, pipe as pipe_inner}; /// # Ok(()) /// # } /// ``` +/// [changes]: io#platform-specific-behavior /// [man page]: https://man7.org/linux/man-pages/man7/pipe.7.html #[unstable(feature = "anonymous_pipe", issue = "127154")] #[inline] @@ -85,15 +93,15 @@ impl PipeReader { /// # #[cfg(miri)] fn main() {} /// # #[cfg(not(miri))] /// # fn main() -> std::io::Result<()> { - /// # use std::fs; - /// # use std::io::Write; - /// # use std::process::Command; + /// use std::fs; + /// use std::io::{pipe, Write}; + /// use std::process::Command; /// const NUM_SLOT: u8 = 2; /// const NUM_PROC: u8 = 5; /// const OUTPUT: &str = "work.txt"; /// /// let mut jobs = vec![]; - /// let (reader, mut writer) = std::io::pipe()?; + /// let (reader, mut writer) = pipe()?; /// /// // Write NUM_SLOT characters the pipe. /// writer.write_all(&[b'|'; NUM_SLOT as usize])?; @@ -145,9 +153,9 @@ impl PipeWriter { /// # #[cfg(miri)] fn main() {} /// # #[cfg(not(miri))] /// # fn main() -> std::io::Result<()> { - /// # use std::process::Command; - /// # use std::io::Read; - /// let (mut reader, writer) = std::io::pipe()?; + /// use std::process::Command; + /// use std::io::{pipe, Read}; + /// let (mut reader, writer) = pipe()?; /// /// // Spawn a process that writes to stdout and stderr. /// let mut peer = Command::new("bash") @@ -224,11 +232,9 @@ impl io::Write for &PipeWriter { fn flush(&mut self) -> io::Result<()> { Ok(()) } - fn write_vectored(&mut self, bufs: &[io::IoSlice<'_>]) -> io::Result { self.0.write_vectored(bufs) } - #[inline] fn is_write_vectored(&self) -> bool { self.0.is_write_vectored() @@ -244,11 +250,9 @@ impl io::Write for PipeWriter { fn flush(&mut self) -> io::Result<()> { Ok(()) } - fn write_vectored(&mut self, bufs: &[io::IoSlice<'_>]) -> io::Result { self.0.write_vectored(bufs) } - #[inline] fn is_write_vectored(&self) -> bool { self.0.is_write_vectored() From 6f543d5cebe220595174a135eca92765df8c97e3 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Fri, 24 Jan 2025 16:19:25 +0000 Subject: [PATCH 58/81] Add regression test --- tests/ui/parallel-rustc/cycle_crash.rs | 5 +++++ tests/ui/parallel-rustc/cycle_crash.stderr | 18 ++++++++++++++++++ 2 files changed, 23 insertions(+) create mode 100644 tests/ui/parallel-rustc/cycle_crash.rs create mode 100644 tests/ui/parallel-rustc/cycle_crash.stderr diff --git a/tests/ui/parallel-rustc/cycle_crash.rs b/tests/ui/parallel-rustc/cycle_crash.rs new file mode 100644 index 000000000000..94ae11aef39d --- /dev/null +++ b/tests/ui/parallel-rustc/cycle_crash.rs @@ -0,0 +1,5 @@ +//@ compile-flags: -Z threads=2 + +const FOO: usize = FOO; //~ERROR cycle detected when simplifying constant for the type system `FOO` + +fn main() {} diff --git a/tests/ui/parallel-rustc/cycle_crash.stderr b/tests/ui/parallel-rustc/cycle_crash.stderr new file mode 100644 index 000000000000..7af3b8ee532c --- /dev/null +++ b/tests/ui/parallel-rustc/cycle_crash.stderr @@ -0,0 +1,18 @@ +error[E0391]: cycle detected when simplifying constant for the type system `FOO` + --> $DIR/cycle_crash.rs:3:1 + | +LL | const FOO: usize = FOO; + | ^^^^^^^^^^^^^^^^ + | +note: ...which requires const-evaluating + checking `FOO`... + --> $DIR/cycle_crash.rs:3:20 + | +LL | const FOO: usize = FOO; + | ^^^ + = note: ...which again requires simplifying constant for the type system `FOO`, completing the cycle + = note: cycle used when running analysis passes on this crate + = note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0391`. From 3779b8e32e405e81d234531a3b4e29ed3c13db8e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rn=20Horstmann?= Date: Wed, 4 Jan 2023 23:55:40 +0100 Subject: [PATCH 59/81] Consistently use the most significant bit of vector masks This improves the codegen for vector `select`, `gather`, `scatter` and boolean reduction intrinsics and fixes rust-lang/portable-simd#316. The current behavior of most mask operations during llvm codegen is to truncate the mask vector to , telling llvm to use the least significat bit. The exception is the `simd_bitmask` intrinsics, which already used the most signifiant bit. Since sse/avx instructions are defined to use the most significant bit, truncating means that llvm has to insert a left shift to move the bit into the most significant position, before the mask can actually be used. Similarly on aarch64, mask operations like blend work bit by bit, repeating the least significant bit across the whole lane involves shifting it into the sign position and then comparing against zero. By shifting before truncating to , we tell llvm that we only consider the most significant bit, removing the need for additional shift instructions in the assembly. --- compiler/rustc_codegen_llvm/src/intrinsic.rs | 197 +++++++++--------- tests/assembly/simd-intrinsic-gather.rs | 4 +- tests/assembly/simd-intrinsic-mask-load.rs | 27 ++- tests/assembly/simd-intrinsic-mask-reduce.rs | 25 +-- tests/assembly/simd-intrinsic-mask-store.rs | 24 +-- tests/assembly/simd-intrinsic-scatter.rs | 4 +- tests/assembly/simd-intrinsic-select.rs | 48 ++--- .../simd-intrinsic-generic-gather.rs | 8 +- .../simd-intrinsic-generic-masked-load.rs | 8 +- .../simd-intrinsic-generic-masked-store.rs | 8 +- .../simd-intrinsic-generic-scatter.rs | 8 +- .../simd-intrinsic-generic-select.rs | 26 ++- .../simd-intrinsic-mask-reduce.rs | 65 ++++++ 13 files changed, 280 insertions(+), 172 deletions(-) create mode 100644 tests/codegen/simd-intrinsic/simd-intrinsic-mask-reduce.rs diff --git a/compiler/rustc_codegen_llvm/src/intrinsic.rs b/compiler/rustc_codegen_llvm/src/intrinsic.rs index 91b44b084b09..eab4a9f30c9d 100644 --- a/compiler/rustc_codegen_llvm/src/intrinsic.rs +++ b/compiler/rustc_codegen_llvm/src/intrinsic.rs @@ -1182,6 +1182,60 @@ fn generic_simd_intrinsic<'ll, 'tcx>( }}; } + /// Returns the bitwidth of the `$ty` argument if it is an `Int` type. + macro_rules! require_int_ty { + ($ty: expr, $diag: expr) => { + match $ty { + ty::Int(i) => i.bit_width().unwrap_or_else(|| bx.data_layout().pointer_size.bits()), + _ => { + return_error!($diag); + } + } + }; + } + + /// Returns the bitwidth of the `$ty` argument if it is an `Int` or `Uint` type. + macro_rules! require_int_or_uint_ty { + ($ty: expr, $diag: expr) => { + match $ty { + ty::Int(i) => i.bit_width().unwrap_or_else(|| bx.data_layout().pointer_size.bits()), + ty::Uint(i) => { + i.bit_width().unwrap_or_else(|| bx.data_layout().pointer_size.bits()) + } + _ => { + return_error!($diag); + } + } + }; + } + + /// Converts a vector mask, where each element has a bit width equal to the data elements it is used with, + /// down to an i1 based mask that can be used by llvm intrinsics. + /// + /// The rust simd semantics are that each element should either consist of all ones or all zeroes, + /// but this information is not available to llvm. Truncating the vector effectively uses the lowest bit, + /// but codegen for several targets is better if we consider the highest bit by shifting. + /// + /// For x86 SSE/AVX targets this is beneficial since most instructions with mask parameters only consider the highest bit. + /// So even though on llvm level we have an additional shift, in the final assembly there is no shift or truncate and + /// instead the mask can be used as is. + /// + /// For aarch64 and other targets there is a benefit because a mask from the sign bit can be more + /// efficiently converted to an all ones / all zeroes mask by comparing whether each element is negative. + fn vector_mask_to_bitmask<'a, 'll, 'tcx>( + bx: &mut Builder<'a, 'll, 'tcx>, + i_xn: &'ll Value, + in_elem_bitwidth: u64, + in_len: u64, + ) -> &'ll Value { + // Shift the MSB to the right by "in_elem_bitwidth - 1" into the first bit position. + let shift_idx = bx.cx.const_int(bx.type_ix(in_elem_bitwidth), (in_elem_bitwidth - 1) as _); + let shift_indices = vec![shift_idx; in_len as _]; + let i_xn_msb = bx.lshr(i_xn, bx.const_vector(shift_indices.as_slice())); + // Truncate vector to an + bx.trunc(i_xn_msb, bx.type_vector(bx.type_i1(), in_len)) + } + let tcx = bx.tcx(); let sig = tcx.normalize_erasing_late_bound_regions(bx.typing_env(), callee_ty.fn_sig(tcx)); let arg_tys = sig.inputs(); @@ -1433,14 +1487,13 @@ fn generic_simd_intrinsic<'ll, 'tcx>( m_len, v_len }); - match m_elem_ty.kind() { - ty::Int(_) => {} - _ => return_error!(InvalidMonomorphization::MaskType { span, name, ty: m_elem_ty }), - } - // truncate the mask to a vector of i1s - let i1 = bx.type_i1(); - let i1xn = bx.type_vector(i1, m_len as u64); - let m_i1s = bx.trunc(args[0].immediate(), i1xn); + let in_elem_bitwidth = + require_int_ty!(m_elem_ty.kind(), InvalidMonomorphization::MaskType { + span, + name, + ty: m_elem_ty + }); + let m_i1s = vector_mask_to_bitmask(bx, args[0].immediate(), in_elem_bitwidth, m_len); return Ok(bx.select(m_i1s, args[1].immediate(), args[2].immediate())); } @@ -1457,33 +1510,15 @@ fn generic_simd_intrinsic<'ll, 'tcx>( let expected_bytes = in_len.div_ceil(8); // Integer vector : - let (i_xn, in_elem_bitwidth) = match in_elem.kind() { - ty::Int(i) => ( - args[0].immediate(), - i.bit_width().unwrap_or_else(|| bx.data_layout().pointer_size.bits()), - ), - ty::Uint(i) => ( - args[0].immediate(), - i.bit_width().unwrap_or_else(|| bx.data_layout().pointer_size.bits()), - ), - _ => return_error!(InvalidMonomorphization::VectorArgument { + let in_elem_bitwidth = + require_int_or_uint_ty!(in_elem.kind(), InvalidMonomorphization::VectorArgument { span, name, in_ty, in_elem - }), - }; + }); - // LLVM doesn't always know the inputs are `0` or `!0`, so we shift here so it optimizes to - // `pmovmskb` and similar on x86. - let shift_indices = - vec![ - bx.cx.const_int(bx.type_ix(in_elem_bitwidth), (in_elem_bitwidth - 1) as _); - in_len as _ - ]; - let i_xn_msb = bx.lshr(i_xn, bx.const_vector(shift_indices.as_slice())); - // Truncate vector to an - let i1xn = bx.trunc(i_xn_msb, bx.type_vector(bx.type_i1(), in_len)); + let i1xn = vector_mask_to_bitmask(bx, args[0].immediate(), in_elem_bitwidth, in_len); // Bitcast to iN: let i_ = bx.bitcast(i1xn, bx.type_ix(in_len)); @@ -1704,28 +1739,21 @@ fn generic_simd_intrinsic<'ll, 'tcx>( } ); - match element_ty2.kind() { - ty::Int(_) => (), - _ => { - return_error!(InvalidMonomorphization::ThirdArgElementType { - span, - name, - expected_element: element_ty2, - third_arg: arg_tys[2] - }); - } - } + let mask_elem_bitwidth = + require_int_ty!(element_ty2.kind(), InvalidMonomorphization::ThirdArgElementType { + span, + name, + expected_element: element_ty2, + third_arg: arg_tys[2] + }); // Alignment of T, must be a constant integer value: let alignment_ty = bx.type_i32(); let alignment = bx.const_i32(bx.align_of(in_elem).bytes() as i32); // Truncate the mask vector to a vector of i1s: - let (mask, mask_ty) = { - let i1 = bx.type_i1(); - let i1xn = bx.type_vector(i1, in_len); - (bx.trunc(args[2].immediate(), i1xn), i1xn) - }; + let mask = vector_mask_to_bitmask(bx, args[2].immediate(), mask_elem_bitwidth, in_len); + let mask_ty = bx.type_vector(bx.type_i1(), in_len); // Type of the vector of pointers: let llvm_pointer_vec_ty = llvm_vector_ty(bx, element_ty1, in_len); @@ -1810,27 +1838,21 @@ fn generic_simd_intrinsic<'ll, 'tcx>( } ); - require!( - matches!(mask_elem.kind(), ty::Int(_)), - InvalidMonomorphization::ThirdArgElementType { + let m_elem_bitwidth = + require_int_ty!(mask_elem.kind(), InvalidMonomorphization::ThirdArgElementType { span, name, expected_element: values_elem, third_arg: mask_ty, - } - ); + }); + + let mask = vector_mask_to_bitmask(bx, args[0].immediate(), m_elem_bitwidth, mask_len); + let mask_ty = bx.type_vector(bx.type_i1(), mask_len); // Alignment of T, must be a constant integer value: let alignment_ty = bx.type_i32(); let alignment = bx.const_i32(bx.align_of(values_elem).bytes() as i32); - // Truncate the mask vector to a vector of i1s: - let (mask, mask_ty) = { - let i1 = bx.type_i1(); - let i1xn = bx.type_vector(i1, mask_len); - (bx.trunc(args[0].immediate(), i1xn), i1xn) - }; - let llvm_pointer = bx.type_ptr(); // Type of the vector of elements: @@ -1901,27 +1923,21 @@ fn generic_simd_intrinsic<'ll, 'tcx>( } ); - require!( - matches!(mask_elem.kind(), ty::Int(_)), - InvalidMonomorphization::ThirdArgElementType { + let m_elem_bitwidth = + require_int_ty!(mask_elem.kind(), InvalidMonomorphization::ThirdArgElementType { span, name, expected_element: values_elem, third_arg: mask_ty, - } - ); + }); + + let mask = vector_mask_to_bitmask(bx, args[0].immediate(), m_elem_bitwidth, mask_len); + let mask_ty = bx.type_vector(bx.type_i1(), mask_len); // Alignment of T, must be a constant integer value: let alignment_ty = bx.type_i32(); let alignment = bx.const_i32(bx.align_of(values_elem).bytes() as i32); - // Truncate the mask vector to a vector of i1s: - let (mask, mask_ty) = { - let i1 = bx.type_i1(); - let i1xn = bx.type_vector(i1, in_len); - (bx.trunc(args[0].immediate(), i1xn), i1xn) - }; - let ret_t = bx.type_void(); let llvm_pointer = bx.type_ptr(); @@ -1995,28 +2011,21 @@ fn generic_simd_intrinsic<'ll, 'tcx>( ); // The element type of the third argument must be a signed integer type of any width: - match element_ty2.kind() { - ty::Int(_) => (), - _ => { - return_error!(InvalidMonomorphization::ThirdArgElementType { - span, - name, - expected_element: element_ty2, - third_arg: arg_tys[2] - }); - } - } + let mask_elem_bitwidth = + require_int_ty!(element_ty2.kind(), InvalidMonomorphization::ThirdArgElementType { + span, + name, + expected_element: element_ty2, + third_arg: arg_tys[2] + }); // Alignment of T, must be a constant integer value: let alignment_ty = bx.type_i32(); let alignment = bx.const_i32(bx.align_of(in_elem).bytes() as i32); // Truncate the mask vector to a vector of i1s: - let (mask, mask_ty) = { - let i1 = bx.type_i1(); - let i1xn = bx.type_vector(i1, in_len); - (bx.trunc(args[2].immediate(), i1xn), i1xn) - }; + let mask = vector_mask_to_bitmask(bx, args[2].immediate(), mask_elem_bitwidth, in_len); + let mask_ty = bx.type_vector(bx.type_i1(), in_len); let ret_t = bx.type_void(); @@ -2164,8 +2173,13 @@ fn generic_simd_intrinsic<'ll, 'tcx>( }); args[0].immediate() } else { - match in_elem.kind() { - ty::Int(_) | ty::Uint(_) => {} + let bitwidth = match in_elem.kind() { + ty::Int(i) => { + i.bit_width().unwrap_or_else(|| bx.data_layout().pointer_size.bits()) + } + ty::Uint(i) => { + i.bit_width().unwrap_or_else(|| bx.data_layout().pointer_size.bits()) + } _ => return_error!(InvalidMonomorphization::UnsupportedSymbol { span, name, @@ -2174,12 +2188,9 @@ fn generic_simd_intrinsic<'ll, 'tcx>( in_elem, ret_ty }), - } + }; - // boolean reductions operate on vectors of i1s: - let i1 = bx.type_i1(); - let i1xn = bx.type_vector(i1, in_len as u64); - bx.trunc(args[0].immediate(), i1xn) + vector_mask_to_bitmask(bx, args[0].immediate(), bitwidth, in_len as _) }; return match in_elem.kind() { ty::Int(_) | ty::Uint(_) => { diff --git a/tests/assembly/simd-intrinsic-gather.rs b/tests/assembly/simd-intrinsic-gather.rs index d2b5a1507f0c..29b0df640655 100644 --- a/tests/assembly/simd-intrinsic-gather.rs +++ b/tests/assembly/simd-intrinsic-gather.rs @@ -35,8 +35,8 @@ pub unsafe extern "C" fn gather_f64x4(mask: m64x4, ptrs: pf64x4) -> f64x4 { // FIXME: This should also get checked to generate a gather instruction for avx2. // Currently llvm scalarizes this code, see https://github.com/llvm/llvm-project/issues/59789 // - // x86-avx512: vpsllq ymm0, ymm0, 63 - // x86-avx512-NEXT: vpmovq2m k1, ymm0 + // x86-avx512-NOT: vpsllq + // x86-avx512: vpmovq2m k1, ymm0 // x86-avx512-NEXT: vpxor xmm0, xmm0, xmm0 // x86-avx512-NEXT: vgatherqpd ymm0 {k1}, {{(ymmword)|(qword)}} ptr [1*ymm1] simd_gather(f64x4([0_f64, 0_f64, 0_f64, 0_f64]), ptrs, mask) diff --git a/tests/assembly/simd-intrinsic-mask-load.rs b/tests/assembly/simd-intrinsic-mask-load.rs index b650e1cee303..89b35ed7734e 100644 --- a/tests/assembly/simd-intrinsic-mask-load.rs +++ b/tests/assembly/simd-intrinsic-mask-load.rs @@ -47,9 +47,9 @@ extern "rust-intrinsic" { pub unsafe extern "C" fn load_i8x16(mask: m8x16, pointer: *const i8) -> i8x16 { // Since avx2 supports no masked loads for bytes, the code tests each individual bit // and jumps to code that inserts individual bytes. - // x86-avx2: vpsllw xmm0, xmm0, 7 - // x86-avx2-NEXT: vpmovmskb eax, xmm0 - // x86-avx2-NEXT: vpxor xmm0, xmm0 + // x86-avx2-NOT: vpsllw + // x86-avx2-DAG: vpmovmskb eax + // x86-avx2-DAG: vpxor // x86-avx2-NEXT: test al, 1 // x86-avx2-NEXT: jne // x86-avx2-NEXT: test al, 2 @@ -58,8 +58,8 @@ pub unsafe extern "C" fn load_i8x16(mask: m8x16, pointer: *const i8) -> i8x16 { // x86-avx2-NEXT: vmovd xmm0, [[REG]] // x86-avx2-DAG: vpinsrb xmm0, xmm0, byte ptr [rdi + 1], 1 // - // x86-avx512: vpsllw xmm0, xmm0, 7 - // x86-avx512-NEXT: vpmovb2m k1, xmm0 + // x86-avx512-NOT: vpsllw + // x86-avx512: vpmovb2m k1, xmm0 // x86-avx512-NEXT: vmovdqu8 xmm0 {k1} {z}, xmmword ptr [rdi] simd_masked_load(mask, pointer, i8x16([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0])) } @@ -67,11 +67,11 @@ pub unsafe extern "C" fn load_i8x16(mask: m8x16, pointer: *const i8) -> i8x16 { // CHECK-LABEL: load_f32x8 #[no_mangle] pub unsafe extern "C" fn load_f32x8(mask: m32x8, pointer: *const f32) -> f32x8 { - // x86-avx2: vpslld ymm0, ymm0, 31 - // x86-avx2-NEXT: vmaskmovps ymm0, ymm0, ymmword ptr [rdi] + // x86-avx2-NOT: vpslld + // x86-avx2: vmaskmovps ymm0, ymm0, ymmword ptr [rdi] // - // x86-avx512: vpslld ymm0, ymm0, 31 - // x86-avx512-NEXT: vpmovd2m k1, ymm0 + // x86-avx512-NOT: vpslld + // x86-avx512: vpmovd2m k1, ymm0 // x86-avx512-NEXT: vmovups ymm0 {k1} {z}, ymmword ptr [rdi] simd_masked_load(mask, pointer, f32x8([0_f32, 0_f32, 0_f32, 0_f32, 0_f32, 0_f32, 0_f32, 0_f32])) } @@ -79,11 +79,10 @@ pub unsafe extern "C" fn load_f32x8(mask: m32x8, pointer: *const f32) -> f32x8 { // CHECK-LABEL: load_f64x4 #[no_mangle] pub unsafe extern "C" fn load_f64x4(mask: m64x4, pointer: *const f64) -> f64x4 { - // x86-avx2: vpsllq ymm0, ymm0, 63 - // x86-avx2-NEXT: vmaskmovpd ymm0, ymm0, ymmword ptr [rdi] + // x86-avx2-NOT: vpsllq + // x86-avx2: vmaskmovpd ymm0, ymm0, ymmword ptr [rdi] // - // x86-avx512: vpsllq ymm0, ymm0, 63 - // x86-avx512-NEXT: vpmovq2m k1, ymm0 - // x86-avx512-NEXT: vmovupd ymm0 {k1} {z}, ymmword ptr [rdi] + // x86-avx512-NOT: vpsllq + // x86-avx512: vpmovq2m k1, ymm0 simd_masked_load(mask, pointer, f64x4([0_f64, 0_f64, 0_f64, 0_f64])) } diff --git a/tests/assembly/simd-intrinsic-mask-reduce.rs b/tests/assembly/simd-intrinsic-mask-reduce.rs index 61d7aa590938..8ac55990c734 100644 --- a/tests/assembly/simd-intrinsic-mask-reduce.rs +++ b/tests/assembly/simd-intrinsic-mask-reduce.rs @@ -31,29 +31,30 @@ extern "rust-intrinsic" { // CHECK-LABEL: mask_reduce_all: #[no_mangle] pub unsafe extern "C" fn mask_reduce_all(m: mask8x16) -> bool { - // x86: psllw xmm0, 7 - // x86-NEXT: pmovmskb eax, xmm0 - // x86-NEXT: {{cmp ax, -1|xor eax, 65535}} + // x86-NOT: psllw + // x86: pmovmskb eax, xmm0 + // x86-NEXT: {{cmp ax, -1|cmp eax, 65535|xor eax, 65535}} // x86-NEXT: sete al // - // aarch64: shl v0.16b, v0.16b, #7 - // aarch64-NEXT: cmlt v0.16b, v0.16b, #0 - // aarch64-NEXT: uminv b0, v0.16b - // aarch64-NEXT: fmov [[REG:[a-z0-9]+]], s0 - // aarch64-NEXT: and w0, [[REG]], #0x1 + // aarch64-NOT: shl + // aarch64: cmge v0.16b, v0.16b, #0 + // aarch64-DAG: mov [[REG1:[a-z0-9]+]], #1 + // aarch64-DAG: umaxv b0, v0.16b + // aarch64-NEXT: fmov [[REG2:[a-z0-9]+]], s0 + // aarch64-NEXT: bic w0, [[REG1]], [[REG2]] simd_reduce_all(m) } // CHECK-LABEL: mask_reduce_any: #[no_mangle] pub unsafe extern "C" fn mask_reduce_any(m: mask8x16) -> bool { - // x86: psllw xmm0, 7 - // x86-NEXT: pmovmskb + // x86-NOT: psllw + // x86: pmovmskb // x86-NEXT: test eax, eax // x86-NEXT: setne al // - // aarch64: shl v0.16b, v0.16b, #7 - // aarch64-NEXT: cmlt v0.16b, v0.16b, #0 + // aarch64-NOT: shl + // aarch64: cmlt v0.16b, v0.16b, #0 // aarch64-NEXT: umaxv b0, v0.16b // aarch64-NEXT: fmov [[REG:[a-z0-9]+]], s0 // aarch64-NEXT: and w0, [[REG]], #0x1 diff --git a/tests/assembly/simd-intrinsic-mask-store.rs b/tests/assembly/simd-intrinsic-mask-store.rs index 95a3b28b9679..1686fd5dd883 100644 --- a/tests/assembly/simd-intrinsic-mask-store.rs +++ b/tests/assembly/simd-intrinsic-mask-store.rs @@ -47,8 +47,8 @@ extern "rust-intrinsic" { pub unsafe extern "C" fn store_i8x16(mask: m8x16, pointer: *mut i8, value: i8x16) { // Since avx2 supports no masked stores for bytes, the code tests each individual bit // and jumps to code that extracts individual bytes to memory. - // x86-avx2: vpsllw xmm0, xmm0, 7 - // x86-avx2-NEXT: vpmovmskb eax, xmm0 + // x86-avx2-NOT: vpsllw + // x86-avx2: vpmovmskb eax, xmm0 // x86-avx2-NEXT: test al, 1 // x86-avx2-NEXT: jne // x86-avx2-NEXT: test al, 2 @@ -56,8 +56,8 @@ pub unsafe extern "C" fn store_i8x16(mask: m8x16, pointer: *mut i8, value: i8x16 // x86-avx2-DAG: vpextrb byte ptr [rdi + 1], xmm1, 1 // x86-avx2-DAG: vpextrb byte ptr [rdi], xmm1, 0 // - // x86-avx512: vpsllw xmm0, xmm0, 7 - // x86-avx512-NEXT: vpmovb2m k1, xmm0 + // x86-avx512-NOT: vpsllw + // x86-avx512: vpmovb2m k1, xmm0 // x86-avx512-NEXT: vmovdqu8 xmmword ptr [rdi] {k1}, xmm1 simd_masked_store(mask, pointer, value) } @@ -65,11 +65,11 @@ pub unsafe extern "C" fn store_i8x16(mask: m8x16, pointer: *mut i8, value: i8x16 // CHECK-LABEL: store_f32x8 #[no_mangle] pub unsafe extern "C" fn store_f32x8(mask: m32x8, pointer: *mut f32, value: f32x8) { - // x86-avx2: vpslld ymm0, ymm0, 31 - // x86-avx2-NEXT: vmaskmovps ymmword ptr [rdi], ymm0, ymm1 + // x86-avx2-NOT: vpslld + // x86-avx2: vmaskmovps ymmword ptr [rdi], ymm0, ymm1 // - // x86-avx512: vpslld ymm0, ymm0, 31 - // x86-avx512-NEXT: vpmovd2m k1, ymm0 + // x86-avx512-NOT: vpslld + // x86-avx512: vpmovd2m k1, ymm0 // x86-avx512-NEXT: vmovups ymmword ptr [rdi] {k1}, ymm1 simd_masked_store(mask, pointer, value) } @@ -77,11 +77,11 @@ pub unsafe extern "C" fn store_f32x8(mask: m32x8, pointer: *mut f32, value: f32x // CHECK-LABEL: store_f64x4 #[no_mangle] pub unsafe extern "C" fn store_f64x4(mask: m64x4, pointer: *mut f64, value: f64x4) { - // x86-avx2: vpsllq ymm0, ymm0, 63 - // x86-avx2-NEXT: vmaskmovpd ymmword ptr [rdi], ymm0, ymm1 + // x86-avx2-NOT: vpsllq + // x86-avx2: vmaskmovpd ymmword ptr [rdi], ymm0, ymm1 // - // x86-avx512: vpsllq ymm0, ymm0, 63 - // x86-avx512-NEXT: vpmovq2m k1, ymm0 + // x86-avx512-NOT: vpsllq + // x86-avx512: vpmovq2m k1, ymm0 // x86-avx512-NEXT: vmovupd ymmword ptr [rdi] {k1}, ymm1 simd_masked_store(mask, pointer, value) } diff --git a/tests/assembly/simd-intrinsic-scatter.rs b/tests/assembly/simd-intrinsic-scatter.rs index f7e08e33faaf..3f4d7569c59f 100644 --- a/tests/assembly/simd-intrinsic-scatter.rs +++ b/tests/assembly/simd-intrinsic-scatter.rs @@ -32,8 +32,8 @@ extern "rust-intrinsic" { // CHECK-LABEL: scatter_f64x4 #[no_mangle] pub unsafe extern "C" fn scatter_f64x4(values: f64x4, ptrs: pf64x4, mask: m64x4) { - // x86-avx512: vpsllq ymm2, ymm2, 63 - // x86-avx512-NEXT: vpmovq2m k1, ymm2 + // x86-avx512-NOT: vpsllq + // x86-avx512: vpmovq2m k1, ymm2 // x86-avx512-NEXT: vscatterqpd {{(ymmword)|(qword)}} ptr [1*ymm1] {k1}, ymm0 simd_scatter(values, ptrs, mask) } diff --git a/tests/assembly/simd-intrinsic-select.rs b/tests/assembly/simd-intrinsic-select.rs index 57fd36fd9e30..803abf2eeb30 100644 --- a/tests/assembly/simd-intrinsic-select.rs +++ b/tests/assembly/simd-intrinsic-select.rs @@ -58,15 +58,15 @@ extern "rust-intrinsic" { // CHECK-LABEL: select_i8x16 #[no_mangle] pub unsafe extern "C" fn select_i8x16(mask: m8x16, a: i8x16, b: i8x16) -> i8x16 { - // x86-avx2: vpsllw xmm0, xmm0, 7 - // x86-avx2-NEXT: vpblendvb xmm0, xmm2, xmm1, xmm0 + // x86-avx2-NOT: vpsllw + // x86-avx2: vpblendvb xmm0, xmm2, xmm1, xmm0 // - // x86-avx512: vpsllw xmm0, xmm0, 7 - // x86-avx512-NEXT: vpmovb2m k1, xmm0 + // x86-avx512-NOT: vpsllw + // x86-avx512: vpmovb2m k1, xmm0 // x86-avx512-NEXT: vpblendmb xmm0 {k1}, xmm2, xmm1 // - // aarch64: shl v0.16b, v0.16b, #7 - // aarch64-NEXT: cmlt v0.16b, v0.16b, #0 + // aarch64-NOT: shl + // aarch64: cmlt v0.16b, v0.16b, #0 // aarch64-NEXT: bsl v0.16b, v1.16b, v2.16b simd_select(mask, a, b) } @@ -74,15 +74,15 @@ pub unsafe extern "C" fn select_i8x16(mask: m8x16, a: i8x16, b: i8x16) -> i8x16 // CHECK-LABEL: select_f32x4 #[no_mangle] pub unsafe extern "C" fn select_f32x4(mask: m32x4, a: f32x4, b: f32x4) -> f32x4 { - // x86-avx2: vpslld xmm0, xmm0, 31 - // x86-avx2-NEXT: vblendvps xmm0, xmm2, xmm1, xmm0 + // x86-avx2-NOT: vpslld + // x86-avx2: vblendvps xmm0, xmm2, xmm1, xmm0 // - // x86-avx512: vpslld xmm0, xmm0, 31 - // x86-avx512-NEXT: vpmovd2m k1, xmm0 + // x86-avx512-NOT: vpslld + // x86-avx512: vpmovd2m k1, xmm0 // x86-avx512-NEXT: vblendmps xmm0 {k1}, xmm2, xmm1 // - // aarch64: shl v0.4s, v0.4s, #31 - // aarch64-NEXT: cmlt v0.4s, v0.4s, #0 + // aarch64-NOT: shl + // aarch64: cmlt v0.4s, v0.4s, #0 // aarch64-NEXT: bsl v0.16b, v1.16b, v2.16b simd_select(mask, a, b) } @@ -90,15 +90,15 @@ pub unsafe extern "C" fn select_f32x4(mask: m32x4, a: f32x4, b: f32x4) -> f32x4 // CHECK-LABEL: select_f64x2 #[no_mangle] pub unsafe extern "C" fn select_f64x2(mask: m64x2, a: f64x2, b: f64x2) -> f64x2 { - // x86-avx2: vpsllq xmm0, xmm0, 63 - // x86-avx2-NEXT: vblendvpd xmm0, xmm2, xmm1, xmm0 + // x86-avx2-NOT: vpsllq + // x86-avx2: vblendvpd xmm0, xmm2, xmm1, xmm0 // - // x86-avx512: vpsllq xmm0, xmm0, 63 - // x86-avx512-NEXT: vpmovq2m k1, xmm0 + // x86-avx512-NOT: vpsllq + // x86-avx512: vpmovq2m k1, xmm0 // x86-avx512-NEXT: vblendmpd xmm0 {k1}, xmm2, xmm1 // - // aarch64: shl v0.2d, v0.2d, #63 - // aarch64-NEXT: cmlt v0.2d, v0.2d, #0 + // aarch64-NOT: shl + // aarch64: cmlt v0.2d, v0.2d, #0 // aarch64-NEXT: bsl v0.16b, v1.16b, v2.16b simd_select(mask, a, b) } @@ -108,11 +108,11 @@ pub unsafe extern "C" fn select_f64x2(mask: m64x2, a: f64x2, b: f64x2) -> f64x2 pub unsafe extern "C" fn select_f64x4(mask: m64x4, a: f64x4, b: f64x4) -> f64x4 { // The parameter is a 256 bit vector which in the C abi is only valid for avx targets. // - // x86-avx2: vpsllq ymm0, ymm0, 63 - // x86-avx2-NEXT: vblendvpd ymm0, ymm2, ymm1, ymm0 + // x86-avx2-NOT: vpsllq + // x86-avx2: vblendvpd ymm0, ymm2, ymm1, ymm0 // - // x86-avx512: vpsllq ymm0, ymm0, 63 - // x86-avx512-NEXT: vpmovq2m k1, ymm0 + // x86-avx512-NOT: vpsllq + // x86-avx512: vpmovq2m k1, ymm0 // x86-avx512-NEXT: vblendmpd ymm0 {k1}, ymm2, ymm1 simd_select(mask, a, b) } @@ -122,8 +122,8 @@ pub unsafe extern "C" fn select_f64x4(mask: m64x4, a: f64x4, b: f64x4) -> f64x4 pub unsafe extern "C" fn select_f64x8(mask: m64x8, a: f64x8, b: f64x8) -> f64x8 { // The parameter is a 256 bit vector which in the C abi is only valid for avx512 targets. // - // x86-avx512: vpsllq zmm0, zmm0, 63 - // x86-avx512-NEXT: vpmovq2m k1, zmm0 + // x86-avx512-NOT: vpsllq + // x86-avx512: vpmovq2m k1, zmm0 // x86-avx512-NEXT: vblendmpd zmm0 {k1}, zmm2, zmm1 simd_select(mask, a, b) } diff --git a/tests/codegen/simd-intrinsic/simd-intrinsic-generic-gather.rs b/tests/codegen/simd-intrinsic/simd-intrinsic-generic-gather.rs index 10ceeecf9007..605a0d520a77 100644 --- a/tests/codegen/simd-intrinsic/simd-intrinsic-generic-gather.rs +++ b/tests/codegen/simd-intrinsic/simd-intrinsic-generic-gather.rs @@ -23,7 +23,9 @@ extern "rust-intrinsic" { #[no_mangle] pub unsafe fn gather_f32x2(pointers: Vec2<*const f32>, mask: Vec2, values: Vec2) -> Vec2 { - // CHECK: call <2 x float> @llvm.masked.gather.v2f32.v2p0(<2 x ptr> {{.*}}, i32 {{.*}}, <2 x i1> {{.*}}, <2 x float> {{.*}}) + // CHECK: [[A:%[0-9]+]] = lshr <2 x i32> {{.*}}, + // CHECK: [[B:%[0-9]+]] = trunc <2 x i32> [[A]] to <2 x i1> + // CHECK: call <2 x float> @llvm.masked.gather.v2f32.v2p0(<2 x ptr> {{.*}}, i32 {{.*}}, <2 x i1> [[B]], <2 x float> {{.*}}) simd_gather(values, pointers, mask) } @@ -31,6 +33,8 @@ pub unsafe fn gather_f32x2(pointers: Vec2<*const f32>, mask: Vec2, #[no_mangle] pub unsafe fn gather_pf32x2(pointers: Vec2<*const *const f32>, mask: Vec2, values: Vec2<*const f32>) -> Vec2<*const f32> { - // CHECK: call <2 x ptr> @llvm.masked.gather.v2p0.v2p0(<2 x ptr> {{.*}}, i32 {{.*}}, <2 x i1> {{.*}}, <2 x ptr> {{.*}}) + // CHECK: [[A:%[0-9]+]] = lshr <2 x i32> {{.*}}, + // CHECK: [[B:%[0-9]+]] = trunc <2 x i32> [[A]] to <2 x i1> + // CHECK: call <2 x ptr> @llvm.masked.gather.v2p0.v2p0(<2 x ptr> {{.*}}, i32 {{.*}}, <2 x i1> [[B]], <2 x ptr> {{.*}}) simd_gather(values, pointers, mask) } diff --git a/tests/codegen/simd-intrinsic/simd-intrinsic-generic-masked-load.rs b/tests/codegen/simd-intrinsic/simd-intrinsic-generic-masked-load.rs index 073dc0ac94d9..015f6fd9cef4 100644 --- a/tests/codegen/simd-intrinsic/simd-intrinsic-generic-masked-load.rs +++ b/tests/codegen/simd-intrinsic/simd-intrinsic-generic-masked-load.rs @@ -21,7 +21,9 @@ extern "rust-intrinsic" { #[no_mangle] pub unsafe fn load_f32x2(mask: Vec2, pointer: *const f32, values: Vec2) -> Vec2 { - // CHECK: call <2 x float> @llvm.masked.load.v2f32.p0(ptr {{.*}}, i32 4, <2 x i1> {{.*}}, <2 x float> {{.*}}) + // CHECK: [[A:%[0-9]+]] = lshr <2 x i32> {{.*}}, + // CHECK: [[B:%[0-9]+]] = trunc <2 x i32> [[A]] to <2 x i1> + // CHECK: call <2 x float> @llvm.masked.load.v2f32.p0(ptr {{.*}}, i32 4, <2 x i1> [[B]], <2 x float> {{.*}}) simd_masked_load(mask, pointer, values) } @@ -29,6 +31,8 @@ pub unsafe fn load_f32x2(mask: Vec2, pointer: *const f32, #[no_mangle] pub unsafe fn load_pf32x4(mask: Vec4, pointer: *const *const f32, values: Vec4<*const f32>) -> Vec4<*const f32> { - // CHECK: call <4 x ptr> @llvm.masked.load.v4p0.p0(ptr {{.*}}, i32 {{.*}}, <4 x i1> {{.*}}, <4 x ptr> {{.*}}) + // CHECK: [[A:%[0-9]+]] = lshr <4 x i32> {{.*}}, + // CHECK: [[B:%[0-9]+]] = trunc <4 x i32> [[A]] to <4 x i1> + // CHECK: call <4 x ptr> @llvm.masked.load.v4p0.p0(ptr {{.*}}, i32 {{.*}}, <4 x i1> [[B]], <4 x ptr> {{.*}}) simd_masked_load(mask, pointer, values) } diff --git a/tests/codegen/simd-intrinsic/simd-intrinsic-generic-masked-store.rs b/tests/codegen/simd-intrinsic/simd-intrinsic-generic-masked-store.rs index 7c3393e6f2e7..471a4bea181b 100644 --- a/tests/codegen/simd-intrinsic/simd-intrinsic-generic-masked-store.rs +++ b/tests/codegen/simd-intrinsic/simd-intrinsic-generic-masked-store.rs @@ -20,13 +20,17 @@ extern "rust-intrinsic" { // CHECK-LABEL: @store_f32x2 #[no_mangle] pub unsafe fn store_f32x2(mask: Vec2, pointer: *mut f32, values: Vec2) { - // CHECK: call void @llvm.masked.store.v2f32.p0(<2 x float> {{.*}}, ptr {{.*}}, i32 4, <2 x i1> {{.*}}) + // CHECK: [[A:%[0-9]+]] = lshr <2 x i32> {{.*}}, + // CHECK: [[B:%[0-9]+]] = trunc <2 x i32> [[A]] to <2 x i1> + // CHECK: call void @llvm.masked.store.v2f32.p0(<2 x float> {{.*}}, ptr {{.*}}, i32 4, <2 x i1> [[B]]) simd_masked_store(mask, pointer, values) } // CHECK-LABEL: @store_pf32x4 #[no_mangle] pub unsafe fn store_pf32x4(mask: Vec4, pointer: *mut *const f32, values: Vec4<*const f32>) { - // CHECK: call void @llvm.masked.store.v4p0.p0(<4 x ptr> {{.*}}, ptr {{.*}}, i32 {{.*}}, <4 x i1> {{.*}}) + // CHECK: [[A:%[0-9]+]] = lshr <4 x i32> {{.*}}, + // CHECK: [[B:%[0-9]+]] = trunc <4 x i32> [[A]] to <4 x i1> + // CHECK: call void @llvm.masked.store.v4p0.p0(<4 x ptr> {{.*}}, ptr {{.*}}, i32 {{.*}}, <4 x i1> [[B]]) simd_masked_store(mask, pointer, values) } diff --git a/tests/codegen/simd-intrinsic/simd-intrinsic-generic-scatter.rs b/tests/codegen/simd-intrinsic/simd-intrinsic-generic-scatter.rs index 3c75ef5be40b..1c42b2534d87 100644 --- a/tests/codegen/simd-intrinsic/simd-intrinsic-generic-scatter.rs +++ b/tests/codegen/simd-intrinsic/simd-intrinsic-generic-scatter.rs @@ -23,7 +23,9 @@ extern "rust-intrinsic" { #[no_mangle] pub unsafe fn scatter_f32x2(pointers: Vec2<*mut f32>, mask: Vec2, values: Vec2) { - // CHECK: call void @llvm.masked.scatter.v2f32.v2p0(<2 x float> {{.*}}, <2 x ptr> {{.*}}, i32 {{.*}}, <2 x i1> {{.*}}) + // CHECK: [[A:%[0-9]+]] = lshr <2 x i32> {{.*}}, + // CHECK: [[B:%[0-9]+]] = trunc <2 x i32> [[A]] to <2 x i1> + // CHECK: call void @llvm.masked.scatter.v2f32.v2p0(<2 x float> {{.*}}, <2 x ptr> {{.*}}, i32 {{.*}}, <2 x i1> [[B]] simd_scatter(values, pointers, mask) } @@ -32,6 +34,8 @@ pub unsafe fn scatter_f32x2(pointers: Vec2<*mut f32>, mask: Vec2, #[no_mangle] pub unsafe fn scatter_pf32x2(pointers: Vec2<*mut *const f32>, mask: Vec2, values: Vec2<*const f32>) { - // CHECK: call void @llvm.masked.scatter.v2p0.v2p0(<2 x ptr> {{.*}}, <2 x ptr> {{.*}}, i32 {{.*}}, <2 x i1> {{.*}}) + // CHECK: [[A:%[0-9]+]] = lshr <2 x i32> {{.*}}, + // CHECK: [[B:%[0-9]+]] = trunc <2 x i32> [[A]] to <2 x i1> + // CHECK: call void @llvm.masked.scatter.v2p0.v2p0(<2 x ptr> {{.*}}, <2 x ptr> {{.*}}, i32 {{.*}}, <2 x i1> [[B]] simd_scatter(values, pointers, mask) } diff --git a/tests/codegen/simd-intrinsic/simd-intrinsic-generic-select.rs b/tests/codegen/simd-intrinsic/simd-intrinsic-generic-select.rs index c12fefa413b2..a73593160f2e 100644 --- a/tests/codegen/simd-intrinsic/simd-intrinsic-generic-select.rs +++ b/tests/codegen/simd-intrinsic/simd-intrinsic-generic-select.rs @@ -3,7 +3,7 @@ #![crate_type = "lib"] #![feature(repr_simd, intrinsics)] -#[allow(non_camel_case_types)] +#![allow(non_camel_case_types)] #[repr(simd)] #[derive(Copy, Clone, PartialEq, Debug)] @@ -17,21 +17,37 @@ pub struct f32x8([f32; 8]); #[derive(Copy, Clone, PartialEq, Debug)] pub struct b8x4(pub [i8; 4]); +#[repr(simd)] +#[derive(Copy, Clone, PartialEq, Debug)] +pub struct i32x4([i32; 4]); + extern "rust-intrinsic" { fn simd_select(x: T, a: U, b: U) -> U; fn simd_select_bitmask(x: T, a: U, b: U) -> U; } -// CHECK-LABEL: @select +// CHECK-LABEL: @select_m8 #[no_mangle] -pub unsafe fn select(m: b8x4, a: f32x4, b: f32x4) -> f32x4 { - // CHECK: select <4 x i1> +pub unsafe fn select_m8(m: b8x4, a: f32x4, b: f32x4) -> f32x4 { + // CHECK: [[A:%[0-9]+]] = lshr <4 x i8> %{{.*}}, + // CHECK: [[B:%[0-9]+]] = trunc <4 x i8> [[A]] to <4 x i1> + // CHECK: select <4 x i1> [[B]] + simd_select(m, a, b) +} + +// CHECK-LABEL: @select_m32 +#[no_mangle] +pub unsafe fn select_m32(m: i32x4, a: f32x4, b: f32x4) -> f32x4 { + // CHECK: [[A:%[0-9]+]] = lshr <4 x i32> %{{.*}}, + // CHECK: [[B:%[0-9]+]] = trunc <4 x i32> [[A]] to <4 x i1> + // CHECK: select <4 x i1> [[B]] simd_select(m, a, b) } // CHECK-LABEL: @select_bitmask #[no_mangle] pub unsafe fn select_bitmask(m: i8, a: f32x8, b: f32x8) -> f32x8 { - // CHECK: select <8 x i1> + // CHECK: [[A:%[0-9]+]] = bitcast i8 {{.*}} to <8 x i1> + // CHECK: select <8 x i1> [[A]] simd_select_bitmask(m, a, b) } diff --git a/tests/codegen/simd-intrinsic/simd-intrinsic-mask-reduce.rs b/tests/codegen/simd-intrinsic/simd-intrinsic-mask-reduce.rs new file mode 100644 index 000000000000..4df246c2f5c7 --- /dev/null +++ b/tests/codegen/simd-intrinsic/simd-intrinsic-mask-reduce.rs @@ -0,0 +1,65 @@ +//@ compile-flags: -C no-prepopulate-passes +// + +#![crate_type = "lib"] +#![feature(repr_simd, intrinsics)] +#![allow(non_camel_case_types)] + +#[repr(simd)] +#[derive(Copy, Clone)] +pub struct mask32x2([i32; 2]); + +#[repr(simd)] +#[derive(Copy, Clone)] +pub struct mask8x16([i8; 16]); + +extern "rust-intrinsic" { + fn simd_reduce_all(x: T) -> bool; + fn simd_reduce_any(x: T) -> bool; +} + +// NOTE(eddyb) `%{{x|1}}` is used because on some targets (e.g. WASM) +// SIMD vectors are passed directly, resulting in `%x` being a vector, +// while on others they're passed indirectly, resulting in `%x` being +// a pointer to a vector, and `%1` a vector loaded from that pointer. +// This is controlled by the target spec option `simd_types_indirect`. + +// CHECK-LABEL: @reduce_any_32x2 +#[no_mangle] +pub unsafe fn reduce_any_32x2(x: mask32x2) -> bool { + // CHECK: [[A:%[0-9]+]] = lshr <2 x i32> %{{x|1}}, + // CHECK: [[B:%[0-9]+]] = trunc <2 x i32> [[A]] to <2 x i1> + // CHECK: [[C:%[0-9]+]] = call i1 @llvm.vector.reduce.or.v2i1(<2 x i1> [[B]]) + // CHECK: %{{[0-9]+}} = zext i1 [[C]] to i8 + simd_reduce_any(x) +} + +// CHECK-LABEL: @reduce_all_32x2 +#[no_mangle] +pub unsafe fn reduce_all_32x2(x: mask32x2) -> bool { + // CHECK: [[A:%[0-9]+]] = lshr <2 x i32> %{{x|1}}, + // CHECK: [[B:%[0-9]+]] = trunc <2 x i32> [[A]] to <2 x i1> + // CHECK: [[C:%[0-9]+]] = call i1 @llvm.vector.reduce.and.v2i1(<2 x i1> [[B]]) + // CHECK: %{{[0-9]+}} = zext i1 [[C]] to i8 + simd_reduce_all(x) +} + +// CHECK-LABEL: @reduce_any_8x16 +#[no_mangle] +pub unsafe fn reduce_any_8x16(x: mask8x16) -> bool { + // CHECK: [[A:%[0-9]+]] = lshr <16 x i8> %{{x|1}}, + // CHECK: [[B:%[0-9]+]] = trunc <16 x i8> [[A]] to <16 x i1> + // CHECK: [[C:%[0-9]+]] = call i1 @llvm.vector.reduce.or.v16i1(<16 x i1> [[B]]) + // CHECK: %{{[0-9]+}} = zext i1 [[C]] to i8 + simd_reduce_any(x) +} + +// CHECK-LABEL: @reduce_all_8x16 +#[no_mangle] +pub unsafe fn reduce_all_8x16(x: mask8x16) -> bool { + // CHECK: [[A:%[0-9]+]] = lshr <16 x i8> %{{x|1}}, + // CHECK: [[B:%[0-9]+]] = trunc <16 x i8> [[A]] to <16 x i1> + // CHECK: [[C:%[0-9]+]] = call i1 @llvm.vector.reduce.and.v16i1(<16 x i1> [[B]]) + // CHECK: %{{[0-9]+}} = zext i1 [[C]] to i8 + simd_reduce_all(x) +} From 614446887ea4e5708f85dac9db008b4f3a20f004 Mon Sep 17 00:00:00 2001 From: Yotam Ofek Date: Sun, 26 Jan 2025 16:25:47 +0000 Subject: [PATCH 60/81] =?UTF-8?q?rustc=5Fast:=20replace=20some=20len-check?= =?UTF-8?q?s=20+=20indexing=20with=20slice=20patterns=20etc.=20?= =?UTF-8?q?=F0=9F=A7=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- compiler/rustc_ast/src/ast.rs | 6 +++--- compiler/rustc_ast/src/attr/mod.rs | 2 +- compiler/rustc_ast/src/mut_visit.rs | 8 ++++---- compiler/rustc_ast/src/util/comments.rs | 4 ++-- 4 files changed, 10 insertions(+), 10 deletions(-) diff --git a/compiler/rustc_ast/src/ast.rs b/compiler/rustc_ast/src/ast.rs index 727fd59c6b30..ad942e9b494a 100644 --- a/compiler/rustc_ast/src/ast.rs +++ b/compiler/rustc_ast/src/ast.rs @@ -100,7 +100,7 @@ pub struct Path { impl PartialEq for Path { #[inline] fn eq(&self, symbol: &Symbol) -> bool { - self.segments.len() == 1 && { self.segments[0].ident.name == *symbol } + matches!(&self.segments[..], [segment] if segment.ident.name == *symbol) } } @@ -121,13 +121,13 @@ impl Path { } pub fn is_global(&self) -> bool { - !self.segments.is_empty() && self.segments[0].ident.name == kw::PathRoot + self.segments.first().is_some_and(|segment| segment.ident.name == kw::PathRoot) } /// If this path is a single identifier with no arguments, does not ensure /// that the path resolves to a const param, the caller should check this. pub fn is_potential_trivial_const_arg(&self) -> bool { - self.segments.len() == 1 && self.segments[0].args.is_none() + matches!(self.segments[..], [PathSegment { args: None, .. }]) } } diff --git a/compiler/rustc_ast/src/attr/mod.rs b/compiler/rustc_ast/src/attr/mod.rs index 51f185800132..df2f4b887124 100644 --- a/compiler/rustc_ast/src/attr/mod.rs +++ b/compiler/rustc_ast/src/attr/mod.rs @@ -302,7 +302,7 @@ impl AttrItem { impl MetaItem { /// For a single-segment meta item, returns its name; otherwise, returns `None`. pub fn ident(&self) -> Option { - if self.path.segments.len() == 1 { Some(self.path.segments[0].ident) } else { None } + if let [PathSegment { ident, .. }] = self.path.segments[..] { Some(ident) } else { None } } pub fn name_or_empty(&self) -> Symbol { diff --git a/compiler/rustc_ast/src/mut_visit.rs b/compiler/rustc_ast/src/mut_visit.rs index aa88e8369d5b..3459d39131ac 100644 --- a/compiler/rustc_ast/src/mut_visit.rs +++ b/compiler/rustc_ast/src/mut_visit.rs @@ -1813,10 +1813,10 @@ pub fn walk_flat_map_stmt( .into_iter() .map(|kind| Stmt { id, kind, span }) .collect(); - match stmts.len() { - 0 => {} - 1 => vis.visit_span(&mut stmts[0].span), - 2.. => panic!( + match &mut stmts[..] { + [] => {} + [stmt] => vis.visit_span(&mut stmt.span), + _ => panic!( "cloning statement `NodeId`s is prohibited by default, \ the visitor should implement custom statement visiting" ), diff --git a/compiler/rustc_ast/src/util/comments.rs b/compiler/rustc_ast/src/util/comments.rs index f39142f08ba5..e12818623d8e 100644 --- a/compiler/rustc_ast/src/util/comments.rs +++ b/compiler/rustc_ast/src/util/comments.rs @@ -39,7 +39,7 @@ pub fn beautify_doc_string(data: Symbol, kind: CommentKind) -> Symbol { let mut i = 0; let mut j = lines.len(); // first line of all-stars should be omitted - if !lines.is_empty() && lines[0].chars().all(|c| c == '*') { + if lines.first().is_some_and(|line| line.chars().all(|c| c == '*')) { i += 1; } @@ -97,7 +97,7 @@ pub fn beautify_doc_string(data: Symbol, kind: CommentKind) -> Symbol { return None; } } - if lines.is_empty() { None } else { Some(lines[0][..i].into()) } + Some(lines.first()?[..i].to_string()) } let data_s = data.as_str(); From 4febbd5c09332776bf1fe7e979f8651705c18b27 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=AE=B8=E6=9D=B0=E5=8F=8B=20Jieyou=20Xu=20=28Joe=29?= <39484203+jieyouxu@users.noreply.github.com> Date: Sat, 25 Jan 2025 15:59:29 +0800 Subject: [PATCH 61/81] bootstrap: avoid glob imports in `main` binary --- src/bootstrap/src/bin/main.rs | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/bootstrap/src/bin/main.rs b/src/bootstrap/src/bin/main.rs index 8ebd6b8aa54c..90bbbf49a776 100644 --- a/src/bootstrap/src/bin/main.rs +++ b/src/bootstrap/src/bin/main.rs @@ -16,11 +16,7 @@ use bootstrap::{ }; use build_helper::ci::CiEnv; #[cfg(feature = "tracing")] -use tracing::*; -#[cfg(feature = "tracing")] -use tracing_subscriber::EnvFilter; -#[cfg(feature = "tracing")] -use tracing_subscriber::prelude::*; +use tracing::{instrument, trace}; #[cfg_attr(feature = "tracing", instrument(level = "trace", name = "main"))] fn main() { @@ -211,6 +207,9 @@ fn check_version(config: &Config) -> Option { // "tracing", instrument(..))]`. #[cfg(feature = "tracing")] fn setup_tracing() { + use tracing_subscriber::EnvFilter; + use tracing_subscriber::layer::SubscriberExt; + let filter = EnvFilter::from_env("BOOTSTRAP_TRACING"); let layer = tracing_tree::HierarchicalLayer::default() .with_writer(std::io::stderr) From 761bda1e432a90892a91f483c857098287847d14 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=AE=B8=E6=9D=B0=E5=8F=8B=20Jieyou=20Xu=20=28Joe=29?= <39484203+jieyouxu@users.noreply.github.com> Date: Sat, 25 Jan 2025 23:10:57 +0800 Subject: [PATCH 62/81] bootstrap: adjust tracing style --- src/bootstrap/src/bin/main.rs | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/src/bootstrap/src/bin/main.rs b/src/bootstrap/src/bin/main.rs index 90bbbf49a776..9f51580d47c4 100644 --- a/src/bootstrap/src/bin/main.rs +++ b/src/bootstrap/src/bin/main.rs @@ -211,15 +211,10 @@ fn setup_tracing() { use tracing_subscriber::layer::SubscriberExt; let filter = EnvFilter::from_env("BOOTSTRAP_TRACING"); - let layer = tracing_tree::HierarchicalLayer::default() - .with_writer(std::io::stderr) - .with_ansi(true) - .with_targets(true) - .with_bracketed_fields(true) - .with_indent_amount(2) - .with_indent_lines(true); - let subscriber = tracing_subscriber::registry().with(filter).with(layer); + // cf. . + let layer = tracing_tree::HierarchicalLayer::default().with_targets(true).with_indent_amount(2); - tracing::subscriber::set_global_default(subscriber).unwrap(); - trace!("tracing subscriber setup"); + let registry = tracing_subscriber::registry().with(filter).with(layer); + + tracing::subscriber::set_global_default(registry).unwrap(); } From 71703bb7d9f19d477a1c88f7ce8d4c9ce0055837 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=AE=B8=E6=9D=B0=E5=8F=8B=20Jieyou=20Xu=20=28Joe=29?= <39484203+jieyouxu@users.noreply.github.com> Date: Sun, 26 Jan 2025 16:06:00 +0800 Subject: [PATCH 63/81] bootstrap: adjust config file cascading fallback comment --- src/bootstrap/src/core/config/config.rs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/bootstrap/src/core/config/config.rs b/src/bootstrap/src/core/config/config.rs index 910550b0a7d3..ec0ba69c62a3 100644 --- a/src/bootstrap/src/core/config/config.rs +++ b/src/bootstrap/src/core/config/config.rs @@ -1418,7 +1418,11 @@ impl Config { config.stage0_metadata = build_helper::stage0_parser::parse_stage0_file(); - // Read from `--config`, then `RUST_BOOTSTRAP_CONFIG`, then `./config.toml`, then `config.toml` in the root directory. + // Find configuration file, with the following cascading fallback (first match wins): + // - `--config ` + // - `RUST_BOOTSTRAP_CONFIG` + // - `./config.toml` + // - `config.toml` in the root directory. let toml_path = flags .config .clone() From 2e1a5320f5ba99e3c5b79752d7ab1b8cabdf4ca7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=AE=B8=E6=9D=B0=E5=8F=8B=20Jieyou=20Xu=20=28Joe=29?= <39484203+jieyouxu@users.noreply.github.com> Date: Sat, 25 Jan 2025 23:11:12 +0800 Subject: [PATCH 64/81] bootstrap: add more logging --- src/bootstrap/src/bin/main.rs | 8 ++++- src/bootstrap/src/core/config/config.rs | 41 +++++++++++++++++++++++++ src/bootstrap/src/core/config/flags.rs | 6 ++++ src/bootstrap/src/lib.rs | 40 +++++++++++++++++++++++- 4 files changed, 93 insertions(+), 2 deletions(-) diff --git a/src/bootstrap/src/bin/main.rs b/src/bootstrap/src/bin/main.rs index 9f51580d47c4..5fcf7eda8df7 100644 --- a/src/bootstrap/src/bin/main.rs +++ b/src/bootstrap/src/bin/main.rs @@ -16,7 +16,7 @@ use bootstrap::{ }; use build_helper::ci::CiEnv; #[cfg(feature = "tracing")] -use tracing::{instrument, trace}; +use tracing::{debug, instrument}; #[cfg_attr(feature = "tracing", instrument(level = "trace", name = "main"))] fn main() { @@ -29,7 +29,11 @@ fn main() { return; } + #[cfg(feature = "tracing")] + debug!("parsing flags"); let flags = Flags::parse(&args); + #[cfg(feature = "tracing")] + debug!("parsing config based on flags"); let config = Config::parse(flags); let mut build_lock; @@ -91,6 +95,8 @@ fn main() { let dump_bootstrap_shims = config.dump_bootstrap_shims; let out_dir = config.out.clone(); + #[cfg(feature = "tracing")] + debug!("creating new build based on config"); Build::new(config).build(); if suggest_setup { diff --git a/src/bootstrap/src/core/config/config.rs b/src/bootstrap/src/core/config/config.rs index ec0ba69c62a3..98490118f7d6 100644 --- a/src/bootstrap/src/core/config/config.rs +++ b/src/bootstrap/src/core/config/config.rs @@ -18,6 +18,8 @@ use build_helper::exit; use build_helper::git::{GitConfig, get_closest_merge_commit, output_result}; use serde::{Deserialize, Deserializer}; use serde_derive::Deserialize; +#[cfg(feature = "tracing")] +use tracing::{instrument, span}; use crate::core::build_steps::compile::CODEGEN_BACKEND_PREFIX; use crate::core::build_steps::llvm; @@ -1227,7 +1229,14 @@ define_config! { } impl Config { + #[cfg_attr( + feature = "tracing", + instrument(target = "CONFIG_HANDLING", level = "trace", name = "Config::default_opts") + )] pub fn default_opts() -> Config { + #[cfg(feature = "tracing")] + span!(target: "CONFIG_HANDLING", tracing::Level::TRACE, "constructing default config"); + Config { bypass_bootstrap_lock: false, llvm_optimize: true, @@ -1311,10 +1320,23 @@ impl Config { }) } + #[cfg_attr( + feature = "tracing", + instrument(target = "CONFIG_HANDLING", level = "trace", name = "Config::parse", skip_all) + )] pub fn parse(flags: Flags) -> Config { Self::parse_inner(flags, Self::get_toml) } + #[cfg_attr( + feature = "tracing", + instrument( + target = "CONFIG_HANDLING", + level = "trace", + name = "Config::parse_inner", + skip_all + ) + )] pub(crate) fn parse_inner( mut flags: Flags, get_toml: impl Fn(&Path) -> Result, @@ -1323,6 +1345,17 @@ impl Config { // Set flags. config.paths = std::mem::take(&mut flags.paths); + + #[cfg(feature = "tracing")] + span!( + target: "CONFIG_HANDLING", + tracing::Level::TRACE, + "collecting paths and path exclusions", + "flags.paths" = ?flags.paths, + "flags.skip" = ?flags.skip, + "flags.exclude" = ?flags.exclude + ); + config.skip = flags .skip .into_iter() @@ -1339,6 +1372,14 @@ impl Config { }) .collect(); + #[cfg(feature = "tracing")] + span!( + target: "CONFIG_HANDLING", + tracing::Level::TRACE, + "normalizing and combining `flag.skip`/`flag.exclude` paths", + "config.skip" = ?config.skip, + ); + config.include_default_paths = flags.include_default_paths; config.rustc_error_format = flags.rustc_error_format; config.json_output = flags.json_output; diff --git a/src/bootstrap/src/core/config/flags.rs b/src/bootstrap/src/core/config/flags.rs index f17103f97dc4..27fb00cb06e0 100644 --- a/src/bootstrap/src/core/config/flags.rs +++ b/src/bootstrap/src/core/config/flags.rs @@ -6,6 +6,8 @@ use std::path::{Path, PathBuf}; use clap::{CommandFactory, Parser, ValueEnum}; +#[cfg(feature = "tracing")] +use tracing::instrument; use crate::core::build_steps::setup::Profile; use crate::core::builder::{Builder, Kind}; @@ -211,6 +213,10 @@ impl Flags { } } + #[cfg_attr( + feature = "tracing", + instrument(level = "trace", name = "Flags::parse", skip_all, fields(args = ?args)) + )] pub fn parse(args: &[String]) -> Self { Flags::parse_from(normalize_args(args)) } diff --git a/src/bootstrap/src/lib.rs b/src/bootstrap/src/lib.rs index 482e23cd04c3..d56f35f866cb 100644 --- a/src/bootstrap/src/lib.rs +++ b/src/bootstrap/src/lib.rs @@ -28,6 +28,8 @@ use std::{env, fs, io, str}; use build_helper::ci::gha; use build_helper::exit; use termcolor::{ColorChoice, StandardStream, WriteColor}; +#[cfg(feature = "tracing")] +use tracing::{debug, instrument, span, trace}; use utils::build_stamp::BuildStamp; use utils::channel::GitInfo; @@ -537,14 +539,25 @@ impl Build { } /// Executes the entire build, as configured by the flags and configuration. + #[cfg_attr(feature = "tracing", instrument(level = "debug", name = "Build::build", skip_all))] pub fn build(&mut self) { + #[cfg(feature = "tracing")] + trace!("setting up job management"); unsafe { crate::utils::job::setup(self); } + #[cfg(feature = "tracing")] + trace!("downloading rustfmt early"); + // Download rustfmt early so that it can be used in rust-analyzer configs. let _ = &builder::Builder::new(self).initial_rustfmt(); + #[cfg(feature = "tracing")] + let hardcoded_span = + span!(tracing::Level::DEBUG, "handling hardcoded subcommands (Format, Suggest, Perf)") + .entered(); + // hardcoded subcommands match &self.config.cmd { Subcommand::Format { check, all } => { @@ -561,25 +574,50 @@ impl Build { Subcommand::Perf { .. } => { return core::build_steps::perf::perf(&builder::Builder::new(self)); } - _ => (), + _cmd => { + #[cfg(feature = "tracing")] + debug!(cmd = ?_cmd, "not a hardcoded subcommand; returning to normal handling"); + } } + #[cfg(feature = "tracing")] + drop(hardcoded_span); + #[cfg(feature = "tracing")] + debug!("handling subcommand normally"); + if !self.config.dry_run() { + #[cfg(feature = "tracing")] + let _real_run_span = span!(tracing::Level::DEBUG, "executing real run").entered(); + { + #[cfg(feature = "tracing")] + let _sanity_check_span = + span!(tracing::Level::DEBUG, "(1) executing dry-run sanity-check").entered(); + // We first do a dry-run. This is a sanity-check to ensure that // steps don't do anything expensive in the dry-run. self.config.dry_run = DryRun::SelfCheck; let builder = builder::Builder::new(self); builder.execute_cli(); } + + #[cfg(feature = "tracing")] + let _actual_run_span = + span!(tracing::Level::DEBUG, "(2) executing actual run").entered(); self.config.dry_run = DryRun::Disabled; let builder = builder::Builder::new(self); builder.execute_cli(); } else { + #[cfg(feature = "tracing")] + let _dry_run_span = span!(tracing::Level::DEBUG, "executing dry run").entered(); + let builder = builder::Builder::new(self); builder.execute_cli(); } + #[cfg(feature = "tracing")] + debug!("checking for postponed test failures from `test --no-fail-fast`"); + // Check for postponed failures from `test --no-fail-fast`. let failures = self.delayed_failures.borrow(); if failures.len() > 0 { From 97efda63b39fdf91c79a663604b7fec5895ab964 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=AE=B8=E6=9D=B0=E5=8F=8B=20Jieyou=20Xu=20=28Joe=29?= <39484203+jieyouxu@users.noreply.github.com> Date: Sat, 25 Jan 2025 15:31:40 +0800 Subject: [PATCH 65/81] rustc-dev-guide: update bootstrap tracing docs --- .../bootstrapping/debugging-bootstrap.md | 90 +++++++++++------- .../tracing-output-example.png | Bin 140711 -> 0 bytes 2 files changed, 58 insertions(+), 32 deletions(-) delete mode 100644 src/doc/rustc-dev-guide/src/building/bootstrapping/debugging-bootstrap/tracing-output-example.png diff --git a/src/doc/rustc-dev-guide/src/building/bootstrapping/debugging-bootstrap.md b/src/doc/rustc-dev-guide/src/building/bootstrapping/debugging-bootstrap.md index 972b4a8fb0e6..3f907e85dd6c 100644 --- a/src/doc/rustc-dev-guide/src/building/bootstrapping/debugging-bootstrap.md +++ b/src/doc/rustc-dev-guide/src/building/bootstrapping/debugging-bootstrap.md @@ -1,6 +1,6 @@ # Debugging bootstrap -> FIXME: this page could be expanded +> FIXME: this section should be expanded ## `tracing` in bootstrap @@ -10,21 +10,69 @@ Bootstrap has conditional [`tracing`][tracing] setup to provide structured loggi ### Enabling `tracing` output -Bootstrap will conditionally enable `tracing` output if the `BOOTSTRAP_TRACING` env var is set. +Bootstrap will conditionally build `tracing` support and enable `tracing` output if the `BOOTSTRAP_TRACING` env var is set. -Example usage: +#### Basic usage + +Example basic usage[^just-trace]: + +[^just-trace]: It is not recommend to use *just* `BOOTSTRAP_TRACING=TRACE` because that will dump *everything* at `TRACE` level, including logs intentionally gated behind custom targets as they are too verbose even for `TRACE` level by default. ```bash -$ BOOTSTRAP_TRACING=TRACE ./x build library --stage 1 +$ BOOTSTRAP_TRACING=bootstrap=TRACE ./x build library --stage 1 ``` -Example output[^experimental]: +Example output[^unstable]: -![Example bootstrap tracing output](./debugging-bootstrap/tracing-output-example.png) +``` +$ BOOTSTRAP_TRACING=bootstrap=TRACE ./x check src/bootstrap/ +Building bootstrap + Compiling bootstrap v0.0.0 (/home/joe/repos/rust/src/bootstrap) + Finished `dev` profile [unoptimized] target(s) in 2.74s + DEBUG bootstrap parsing flags + bootstrap::core::config::flags::Flags::parse args=["check", "src/bootstrap/"] + DEBUG bootstrap parsing config based on flags + DEBUG bootstrap creating new build based on config + bootstrap::Build::build + TRACE bootstrap setting up job management + TRACE bootstrap downloading rustfmt early + bootstrap::handling hardcoded subcommands (Format, Suggest, Perf) + DEBUG bootstrap not a hardcoded subcommand; returning to normal handling, cmd=Check { all_targets: false } + DEBUG bootstrap handling subcommand normally + bootstrap::executing real run + bootstrap::(1) executing dry-run sanity-check + bootstrap::(2) executing actual run +Checking stage0 library artifacts (x86_64-unknown-linux-gnu) + Finished `release` profile [optimized + debuginfo] target(s) in 0.04s +Checking stage0 compiler artifacts {rustc-main, rustc_abi, rustc_arena, rustc_ast, rustc_ast_ir, rustc_ast_lowering, rustc_ast_passes, rustc_ast_pretty, rustc_attr_data_structures, rustc_attr_parsing, rustc_baked_icu_data, rustc_borrowck, rustc_builtin_macros, rustc_codegen_llvm, rustc_codegen_ssa, rustc_const_eval, rustc_data_structures, rustc_driver, rustc_driver_impl, rustc_error_codes, rustc_error_messages, rustc_errors, rustc_expand, rustc_feature, rustc_fluent_macro, rustc_fs_util, rustc_graphviz, rustc_hir, rustc_hir_analysis, rustc_hir_pretty, rustc_hir_typeck, rustc_incremental, rustc_index, rustc_index_macros, rustc_infer, rustc_interface, rustc_lexer, rustc_lint, rustc_lint_defs, rustc_llvm, rustc_log, rustc_macros, rustc_metadata, rustc_middle, rustc_mir_build, rustc_mir_dataflow, rustc_mir_transform, rustc_monomorphize, rustc_next_trait_solver, rustc_parse, rustc_parse_format, rustc_passes, rustc_pattern_analysis, rustc_privacy, rustc_query_impl, rustc_query_system, rustc_resolve, rustc_sanitizers, rustc_serialize, rustc_session, rustc_smir, rustc_span, rustc_symbol_mangling, rustc_target, rustc_trait_selection, rustc_traits, rustc_transmute, rustc_ty_utils, rustc_type_ir, rustc_type_ir_macros, stable_mir} (x86_64-unknown-linux-gnu) + Finished `release` profile [optimized + debuginfo] target(s) in 0.23s +Checking stage0 bootstrap artifacts (x86_64-unknown-linux-gnu) + Checking bootstrap v0.0.0 (/home/joe/repos/rust/src/bootstrap) + Finished `release` profile [optimized + debuginfo] target(s) in 0.64s + DEBUG bootstrap checking for postponed test failures from `test --no-fail-fast` +Build completed successfully in 0:00:08 +``` -[^experimental]: This shows what's *possible* with the infra in an experimental implementation. +#### Controlling log output -The env var `BOOTSTRAP_TRACING` accepts a [`tracing` env-filter][tracing-env-filter]. The `TRACE` filter will enable *all* `trace` level or less verbose level tracing output. +The env var `BOOTSTRAP_TRACING` accepts a [`tracing` env-filter][tracing-env-filter]. + +There are two orthogonal ways to control which kind of logs you want: + +1. You can specify the log **level**, e.g. `DEBUG` or `TRACE`. +2. You can also control the log **target**, e.g. `bootstrap` or `bootstrap::core::config` vs custom targets like `CONFIG_HANDLING`. + - Custom targets are used to limit what is output when `BOOTSTRAP_TRACING=bootstrap=TRACE` is used, as they can be too verbose even for `TRACE` level by default. Currently used custom targets: + - `CONFIG_HANDLING` + +The `TRACE` filter will enable *all* `trace` level or less verbose level tracing output. + +You can of course combine them (custom target logs are typically gated behind `TRACE` log level additionally): + +```bash +$ BOOTSTRAP_TRACING=CONFIG_HANDLING=TRACE ./x build library --stage 1 +``` + +[^unstable]: This output is always subject to further changes. [tracing-env-filter]: https://docs.rs/tracing-subscriber/0.3.19/tracing_subscriber/filter/struct.EnvFilter.html @@ -73,28 +121,6 @@ For `#[instrument]`, it's recommended to: - Explicitly pick an instrumentation name via `name = ".."` to distinguish between e.g. `run` of different steps. - Take care to not cause diverging behavior via tracing, e.g. building extra things only when tracing infra is enabled. -### Enabling `tracing` bootstrap feature in rust-analyzer +### rust-analyzer integration? -You can adjust your `settings.json`'s `rust-analyzer.check.overrideCommand` and `rust-analyzer.cargo.buildScripts.overrideCommand` if you want to also enable `logging` cargo feature by default in your editor. This is mostly useful if you want proper r-a completions and such when working on bootstrap itself. - -```json -"rust-analyzer.check.overrideCommand": [ - "BOOTSTRAP_TRACING=1", // <- BOOTSTRAP_TRACING=1 won't enable tracing filter, but it will activate bootstrap's `tracing` feature - "python3", - "x.py", - "check", - "--json-output", - "--build-dir=build-rust-analyzer" -], -``` - -```json -"rust-analyzer.cargo.buildScripts.overrideCommand": [ - "BOOTSTRAP_TRACING=1", // <- note this - "python3", - "x.py", - "check", - "--json-output", - "--build-dir=build-rust-analyzer" -], -``` +Unfortunately, because bootstrap is a `rust-analyzer.linkedProjects`, you can't ask r-a to check/build bootstrap itself with `tracing` feature enabled to get relevant completions, due to lack of support as described in . diff --git a/src/doc/rustc-dev-guide/src/building/bootstrapping/debugging-bootstrap/tracing-output-example.png b/src/doc/rustc-dev-guide/src/building/bootstrapping/debugging-bootstrap/tracing-output-example.png deleted file mode 100644 index 745aec50d4a36563fa2701a3647506b29576518a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 140711 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 z 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�aXjVEbbSuJ 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

{# #} - Note: Unable to compute type layout, {#+ #} - possibly due to this type having generic parameters. {#+ #} - Layout can only be computed for concrete, fully-instantiated types. {# #} + Note: Unable to compute type layout. {# #}

{# This kind of error probably can't happen with valid code, but we don't want to panic and prevent the docs from building, so we just let the @@ -44,6 +42,14 @@ Note: Encountered an error during type layout; {#+ #} the type was too big. {# #}

+ {# This kind of layout error can occur with valid code, e.g. if you try to + get the layout of a generic type such as `Vec`. #} + {% when Err(LayoutError::TooGeneric(_)) %} +

{# #} + Note: Unable to compute type layout, {#+ #} + possibly due to this type having generic parameters. {#+ #} + Layout can only be computed for concrete, fully-instantiated types. {# #} +

{% when Err(LayoutError::ReferencesError(_)) %}

{# #} Note: Encountered an error during type layout; {#+ #} diff --git a/tests/crashes/135020.rs b/tests/crashes/135020.rs deleted file mode 100644 index b44056eb3af3..000000000000 --- a/tests/crashes/135020.rs +++ /dev/null @@ -1,11 +0,0 @@ -//@ known-bug: #135020 - -pub fn problem_thingy(items: &mut impl Iterator) { - let mut peeker = items.peekable(); - match peeker.peek() { - Some(_) => (), - None => return (), - } -} - -pub fn main() {} diff --git a/tests/rustdoc/type-layout.rs b/tests/rustdoc/type-layout.rs index 1e462210cba2..5f34c8b99e0f 100644 --- a/tests/rustdoc/type-layout.rs +++ b/tests/rustdoc/type-layout.rs @@ -37,7 +37,8 @@ pub struct Y(u8); pub struct Z; // We can't compute layout for generic types. -//@ hasraw type_layout/struct.Generic.html 'Unable to compute type layout, possibly due to this type having generic parameters' +//@ hasraw type_layout/struct.Generic.html 'Unable to compute type layout, possibly due to this type having generic parameters.' +//@ hasraw type_layout/struct.Generic.html 'Layout can only be computed for concrete, fully-instantiated types.' //@ !hasraw - 'Size: ' pub struct Generic(T); @@ -91,3 +92,9 @@ pub enum Uninhabited {} //@ hasraw type_layout/struct.Uninhabited2.html 'Size: ' //@ hasraw - '8 bytes (uninhabited)' pub struct Uninhabited2(std::convert::Infallible, u64); + +pub trait Project { type Assoc; } +// We can't compute layout. A `LayoutError::Unknown` is returned. +//@ hasraw type_layout/struct.Unknown.html 'Unable to compute type layout.' +//@ !hasraw - 'Size: ' +pub struct Unknown(<() as Project>::Assoc) where for<'a> (): Project; diff --git a/tests/ui/enum-discriminant/eval-error.rs b/tests/ui/enum-discriminant/eval-error.rs index f2c3b5816276..08b71d52a8b0 100644 --- a/tests/ui/enum-discriminant/eval-error.rs +++ b/tests/ui/enum-discriminant/eval-error.rs @@ -6,7 +6,7 @@ union Foo { enum Bar { Boo = { - let _: Option = None; + let _: Option = None; //~ ERROR evaluation of constant value failed 0 }, } diff --git a/tests/ui/enum-discriminant/eval-error.stderr b/tests/ui/enum-discriminant/eval-error.stderr index 0f12308de3c1..6bec2c8b420f 100644 --- a/tests/ui/enum-discriminant/eval-error.stderr +++ b/tests/ui/enum-discriminant/eval-error.stderr @@ -45,7 +45,13 @@ help: wrap the field type in `ManuallyDrop<...>` LL | a: std::mem::ManuallyDrop, | +++++++++++++++++++++++ + -error: aborting due to 4 previous errors +error[E0080]: evaluation of constant value failed + --> $DIR/eval-error.rs:9:30 + | +LL | let _: Option = None; + | ^^^^ the type `Foo` has an unknown layout -Some errors have detailed explanations: E0277, E0517, E0740. -For more information about an error, try `rustc --explain E0277`. +error: aborting due to 5 previous errors + +Some errors have detailed explanations: E0080, E0277, E0517, E0740. +For more information about an error, try `rustc --explain E0080`. diff --git a/tests/ui/infinite/infinite-instantiation-struct-tail-ice-114484.rs b/tests/ui/infinite/infinite-instantiation-struct-tail-ice-114484.rs index 410862c53262..e28b8f373dab 100644 --- a/tests/ui/infinite/infinite-instantiation-struct-tail-ice-114484.rs +++ b/tests/ui/infinite/infinite-instantiation-struct-tail-ice-114484.rs @@ -24,7 +24,7 @@ impl VirtualWrapper { impl MyTrait for VirtualWrapper { fn virtualize(&self) -> &dyn MyTrait { unsafe { virtualize_my_trait(L, self) } - // unsafe { virtualize_my_trait(L, &self.0) } // <-- this code fixes the problem + // unsafe { virtualize_my_trait(L, &self.0) } // <-- this code fixes the problem } } diff --git a/tests/ui/layout/base-layout-is-sized-ice-123078.rs b/tests/ui/layout/base-layout-is-sized-ice-123078.rs index 15f11145f845..b1c33e150755 100644 --- a/tests/ui/layout/base-layout-is-sized-ice-123078.rs +++ b/tests/ui/layout/base-layout-is-sized-ice-123078.rs @@ -8,6 +8,7 @@ struct S { } const C: S = unsafe { std::mem::transmute(()) }; +//~^ ERROR cannot transmute between types of different sizes, or dependently-sized types const _: [(); { C; 0 diff --git a/tests/ui/layout/base-layout-is-sized-ice-123078.stderr b/tests/ui/layout/base-layout-is-sized-ice-123078.stderr index 9181368533a4..d8743d4e6d63 100644 --- a/tests/ui/layout/base-layout-is-sized-ice-123078.stderr +++ b/tests/ui/layout/base-layout-is-sized-ice-123078.stderr @@ -16,6 +16,16 @@ help: the `Box` type always has a statically known size and allocates its conten LL | a: Box<[u8]>, | ++++ + -error: aborting due to 1 previous error +error[E0512]: cannot transmute between types of different sizes, or dependently-sized types + --> $DIR/base-layout-is-sized-ice-123078.rs:10:23 + | +LL | const C: S = unsafe { std::mem::transmute(()) }; + | ^^^^^^^^^^^^^^^^^^^ + | + = note: source type: `()` (0 bits) + = note: target type: `S` (the type `S` has an unknown layout) -For more information about this error, try `rustc --explain E0277`. +error: aborting due to 2 previous errors + +Some errors have detailed explanations: E0277, E0512. +For more information about an error, try `rustc --explain E0277`. diff --git a/tests/ui/layout/invalid-unsized-const-eval.rs b/tests/ui/layout/invalid-unsized-const-eval.rs index 2dec0b0faacf..1f664d30055d 100644 --- a/tests/ui/layout/invalid-unsized-const-eval.rs +++ b/tests/ui/layout/invalid-unsized-const-eval.rs @@ -10,5 +10,6 @@ struct LazyLock { } static EMPTY_SET: LazyLock = todo!(); +//~^ ERROR could not evaluate static initializer fn main() {} diff --git a/tests/ui/layout/invalid-unsized-const-eval.stderr b/tests/ui/layout/invalid-unsized-const-eval.stderr index bf65782b7a80..a434ca9b2c7c 100644 --- a/tests/ui/layout/invalid-unsized-const-eval.stderr +++ b/tests/ui/layout/invalid-unsized-const-eval.stderr @@ -7,6 +7,13 @@ LL | data: (dyn Sync, ()), = help: the trait `Sized` is not implemented for `(dyn Sync + 'static)` = note: only the last element of a tuple may have a dynamically sized type -error: aborting due to 1 previous error +error[E0080]: could not evaluate static initializer + --> $DIR/invalid-unsized-const-eval.rs:12:1 + | +LL | static EMPTY_SET: LazyLock = todo!(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ the type `(dyn Sync, ())` has an unknown layout -For more information about this error, try `rustc --explain E0277`. +error: aborting due to 2 previous errors + +Some errors have detailed explanations: E0080, E0277. +For more information about an error, try `rustc --explain E0080`. diff --git a/tests/ui/layout/invalid-unsized-in-always-sized-tail.stderr b/tests/ui/layout/invalid-unsized-in-always-sized-tail.stderr index 3f565d6ee5ba..f54e97e2a5c7 100644 --- a/tests/ui/layout/invalid-unsized-in-always-sized-tail.stderr +++ b/tests/ui/layout/invalid-unsized-in-always-sized-tail.stderr @@ -18,6 +18,20 @@ LL | struct MySlice(T); | | | this could be changed to `T: ?Sized`... -error: aborting due to 1 previous error +error[E0080]: could not evaluate static initializer + --> $SRC_DIR/core/src/mem/mod.rs:LL:COL + | + = note: the type `MySlice<[bool]>` has an unknown layout + | +note: inside `align_of::` + --> $SRC_DIR/core/src/mem/mod.rs:LL:COL +note: inside `CHECK` + --> $DIR/invalid-unsized-in-always-sized-tail.rs:15:28 + | +LL | static CHECK: () = assert!(align_of::() == 1); + | ^^^^^^^^^^^^^^^^ -For more information about this error, try `rustc --explain E0277`. +error: aborting due to 2 previous errors + +Some errors have detailed explanations: E0080, E0277. +For more information about an error, try `rustc --explain E0080`. diff --git a/tests/ui/layout/issue-unsized-tail-restatic-ice-122488.rs b/tests/ui/layout/issue-unsized-tail-restatic-ice-122488.rs index 96c993035ef1..f84c10d8e5c0 100644 --- a/tests/ui/layout/issue-unsized-tail-restatic-ice-122488.rs +++ b/tests/ui/layout/issue-unsized-tail-restatic-ice-122488.rs @@ -6,5 +6,6 @@ struct ArenaSet::Target>(V, U); //~^ ERROR the size for values of type `V` cannot be known at compilation time const DATA: *const ArenaSet> = std::ptr::null_mut(); +//~^ ERROR evaluation of constant value failed pub fn main() {} diff --git a/tests/ui/layout/issue-unsized-tail-restatic-ice-122488.stderr b/tests/ui/layout/issue-unsized-tail-restatic-ice-122488.stderr index f39cb29868af..220951fab86f 100644 --- a/tests/ui/layout/issue-unsized-tail-restatic-ice-122488.stderr +++ b/tests/ui/layout/issue-unsized-tail-restatic-ice-122488.stderr @@ -22,6 +22,13 @@ help: the `Box` type always has a statically known size and allocates its conten LL | struct ArenaSet::Target>(Box, U); | ++++ + -error: aborting due to 1 previous error +error[E0080]: evaluation of constant value failed + --> $DIR/issue-unsized-tail-restatic-ice-122488.rs:8:1 + | +LL | const DATA: *const ArenaSet> = std::ptr::null_mut(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the type `ArenaSet, [u8]>` has an unknown layout -For more information about this error, try `rustc --explain E0277`. +error: aborting due to 2 previous errors + +Some errors have detailed explanations: E0080, E0277. +For more information about an error, try `rustc --explain E0080`. diff --git a/tests/ui/layout/uncomputable-due-to-trivial-bounds-ice-135138.rs b/tests/ui/layout/uncomputable-due-to-trivial-bounds-ice-135138.rs new file mode 100644 index 000000000000..91280e49dcd7 --- /dev/null +++ b/tests/ui/layout/uncomputable-due-to-trivial-bounds-ice-135138.rs @@ -0,0 +1,11 @@ +#![feature(trivial_bounds)] + +fn return_str() +where + str: Sized, +{ + [(); { let _a: Option = None; 0 }]; + //~^ ERROR evaluation of constant value failed +} + +fn main() {} diff --git a/tests/ui/layout/uncomputable-due-to-trivial-bounds-ice-135138.stderr b/tests/ui/layout/uncomputable-due-to-trivial-bounds-ice-135138.stderr new file mode 100644 index 000000000000..6c7c51db8df7 --- /dev/null +++ b/tests/ui/layout/uncomputable-due-to-trivial-bounds-ice-135138.stderr @@ -0,0 +1,9 @@ +error[E0080]: evaluation of constant value failed + --> $DIR/uncomputable-due-to-trivial-bounds-ice-135138.rs:7:16 + | +LL | [(); { let _a: Option = None; 0 }]; + | ^^ the type `Option` has an unknown layout + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0080`. diff --git a/tests/ui/layout/unexpected-unsized-field-issue-135020.rs b/tests/ui/layout/unexpected-unsized-field-issue-135020.rs new file mode 100644 index 000000000000..c81d037e510f --- /dev/null +++ b/tests/ui/layout/unexpected-unsized-field-issue-135020.rs @@ -0,0 +1,7 @@ +//@ check-pass + +fn problem_thingy(items: &mut impl Iterator) { + items.peekable(); +} + +fn main() {} diff --git a/tests/ui/layout/unknown-when-no-type-parameter.rs b/tests/ui/layout/unknown-when-no-type-parameter.rs new file mode 100644 index 000000000000..94c32cf262f2 --- /dev/null +++ b/tests/ui/layout/unknown-when-no-type-parameter.rs @@ -0,0 +1,14 @@ +#![feature(trivial_bounds)] + +//@ error-pattern: error[E0080]: evaluation of constant value failed +//@ error-pattern: the type `<() as Project>::Assoc` has an unknown layout + +trait Project { + type Assoc; +} + +fn foo() where (): Project { + [(); size_of::<<() as Project>::Assoc>()]; +} + +fn main() {} diff --git a/tests/ui/layout/unknown-when-no-type-parameter.stderr b/tests/ui/layout/unknown-when-no-type-parameter.stderr new file mode 100644 index 000000000000..d0456e2b3293 --- /dev/null +++ b/tests/ui/layout/unknown-when-no-type-parameter.stderr @@ -0,0 +1,16 @@ +error[E0080]: evaluation of constant value failed + --> $SRC_DIR/core/src/mem/mod.rs:LL:COL + | + = note: the type `<() as Project>::Assoc` has an unknown layout + | +note: inside `std::mem::size_of::<<() as Project>::Assoc>` + --> $SRC_DIR/core/src/mem/mod.rs:LL:COL +note: inside `foo::{constant#0}` + --> $DIR/unknown-when-no-type-parameter.rs:11:10 + | +LL | [(); size_of::<<() as Project>::Assoc>()]; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0080`. diff --git a/tests/ui/layout/unknown-when-ptr-metadata-is-DST.rs b/tests/ui/layout/unknown-when-ptr-metadata-is-DST.rs new file mode 100644 index 000000000000..973235fe65af --- /dev/null +++ b/tests/ui/layout/unknown-when-ptr-metadata-is-DST.rs @@ -0,0 +1,12 @@ +#![feature(ptr_metadata)] +#![feature(trivial_bounds)] + +fn return_str() +where + str: std::ptr::Pointee, +{ + [(); { let _a: Option<&str> = None; 0 }]; + //~^ ERROR evaluation of constant value failed +} + +fn main() {} diff --git a/tests/ui/layout/unknown-when-ptr-metadata-is-DST.stderr b/tests/ui/layout/unknown-when-ptr-metadata-is-DST.stderr new file mode 100644 index 000000000000..68bba2e96782 --- /dev/null +++ b/tests/ui/layout/unknown-when-ptr-metadata-is-DST.stderr @@ -0,0 +1,9 @@ +error[E0080]: evaluation of constant value failed + --> $DIR/unknown-when-ptr-metadata-is-DST.rs:8:16 + | +LL | [(); { let _a: Option<&str> = None; 0 }]; + | ^^ the type `str` has an unknown layout + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0080`. diff --git a/tests/ui/structs/ice-struct-tail-normalization-113272.rs b/tests/ui/structs/ice-struct-tail-normalization-113272.rs index 0ae24a7b71b4..ce2871fabb8c 100644 --- a/tests/ui/structs/ice-struct-tail-normalization-113272.rs +++ b/tests/ui/structs/ice-struct-tail-normalization-113272.rs @@ -13,6 +13,6 @@ struct Other { fn main() { unsafe { std::mem::transmute::, Option<&Other>>(None); - //~^ ERROR cannot transmute + //~^ ERROR cannot transmute between types of different sizes, or dependently-sized types } } From 9c972c0ea58716a7fcf434cdf96c7b451f82fcaf Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sat, 25 Jan 2025 19:09:50 -0700 Subject: [PATCH 69/81] compiler_fence: fix example --- library/core/src/sync/atomic.rs | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/library/core/src/sync/atomic.rs b/library/core/src/sync/atomic.rs index fda26a672990..859ac1632305 100644 --- a/library/core/src/sync/atomic.rs +++ b/library/core/src/sync/atomic.rs @@ -3727,33 +3727,33 @@ pub fn fence(order: Ordering) { /// /// # Examples /// -/// Without `compiler_fence`, the `assert_eq!` in following code -/// is *not* guaranteed to succeed, despite everything happening in a single thread. -/// To see why, remember that the compiler is free to swap the stores to -/// `IMPORTANT_VARIABLE` and `IS_READY` since they are both -/// `Ordering::Relaxed`. If it does, and the signal handler is invoked right -/// after `IS_READY` is updated, then the signal handler will see -/// `IS_READY=1`, but `IMPORTANT_VARIABLE=0`. -/// Using a `compiler_fence` remedies this situation. +/// Without the two `compiler_fence` calls, the read of `IMPORTANT_VARIABLE` in `signal_handler` +/// is *undefined behavior* due to a data race, despite everything happening in a single thread. +/// This is because the signal handler is considered to run concurrently with its associated +/// thread, and explicit synchronization is required to pass data between a thread and its +/// signal handler. The code below uses two `compiler_fence` calls to establish the usual +/// release-acquire synchronization pattern (see [`fence`] for an image). /// /// ``` -/// use std::sync::atomic::{AtomicBool, AtomicUsize}; +/// use std::sync::atomic::AtomicBool; /// use std::sync::atomic::Ordering; /// use std::sync::atomic::compiler_fence; /// -/// static IMPORTANT_VARIABLE: AtomicUsize = AtomicUsize::new(0); +/// static mut IMPORTANT_VARIABLE: usize = 0; /// static IS_READY: AtomicBool = AtomicBool::new(false); /// /// fn main() { -/// IMPORTANT_VARIABLE.store(42, Ordering::Relaxed); -/// // prevent earlier writes from being moved beyond this point +/// unsafe { IMPORTANT_VARIABLE = 42 }; +/// // Marks earlier writes as being released with future relaxed stores. /// compiler_fence(Ordering::Release); /// IS_READY.store(true, Ordering::Relaxed); /// } /// /// fn signal_handler() { /// if IS_READY.load(Ordering::Relaxed) { -/// assert_eq!(IMPORTANT_VARIABLE.load(Ordering::Relaxed), 42); +/// // Acquires writes that were released with relaxed stores that we read from. +/// compiler_fence(Ordering::Acquire); +/// assert_eq!(unsafe { IMPORTANT_VARIABLE }, 42); /// } /// } /// ``` From ebf53630db4549fca4944be3d5da02daacf26ed4 Mon Sep 17 00:00:00 2001 From: Huang Qi Date: Sat, 25 Jan 2025 11:59:17 +0800 Subject: [PATCH 70/81] Mark all NuttX targets as tier 3 target and support the standard library Signed-off-by: Huang Qi --- .../src/spec/targets/aarch64_unknown_nuttx.rs | 2 +- .../src/spec/targets/armv7a_nuttx_eabi.rs | 2 +- .../src/spec/targets/armv7a_nuttx_eabihf.rs | 2 +- .../targets/riscv32imac_unknown_nuttx_elf.rs | 4 +-- .../targets/riscv32imafc_unknown_nuttx_elf.rs | 4 +-- .../targets/riscv32imc_unknown_nuttx_elf.rs | 4 +-- .../targets/riscv64gc_unknown_nuttx_elf.rs | 4 +-- .../targets/riscv64imac_unknown_nuttx_elf.rs | 4 +-- .../src/spec/targets/thumbv6m_nuttx_eabi.rs | 13 +++---- .../src/spec/targets/thumbv7a_nuttx_eabi.rs | 4 +-- .../src/spec/targets/thumbv7a_nuttx_eabihf.rs | 4 +-- .../src/spec/targets/thumbv7em_nuttx_eabi.rs | 4 +-- .../spec/targets/thumbv7em_nuttx_eabihf.rs | 4 +-- .../src/spec/targets/thumbv7m_nuttx_eabi.rs | 4 +-- .../spec/targets/thumbv8m_base_nuttx_eabi.rs | 4 +-- .../spec/targets/thumbv8m_main_nuttx_eabi.rs | 4 +-- .../targets/thumbv8m_main_nuttx_eabihf.rs | 4 +-- src/doc/rustc/src/platform-support.md | 34 +++++++++---------- 18 files changed, 51 insertions(+), 54 deletions(-) diff --git a/compiler/rustc_target/src/spec/targets/aarch64_unknown_nuttx.rs b/compiler/rustc_target/src/spec/targets/aarch64_unknown_nuttx.rs index 04fd3ec1c26d..582211b02b64 100644 --- a/compiler/rustc_target/src/spec/targets/aarch64_unknown_nuttx.rs +++ b/compiler/rustc_target/src/spec/targets/aarch64_unknown_nuttx.rs @@ -36,7 +36,7 @@ pub(crate) fn target() -> Target { description: Some("AArch64 NuttX".into()), tier: Some(3), host_tools: Some(false), - std: Some(false), + std: Some(true), }, pointer_width: 64, data_layout: "e-m:e-p270:32:32-p271:32:32-p272:64:64-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128-Fn32".into(), diff --git a/compiler/rustc_target/src/spec/targets/armv7a_nuttx_eabi.rs b/compiler/rustc_target/src/spec/targets/armv7a_nuttx_eabi.rs index 138716e8f143..08cbfc743968 100644 --- a/compiler/rustc_target/src/spec/targets/armv7a_nuttx_eabi.rs +++ b/compiler/rustc_target/src/spec/targets/armv7a_nuttx_eabi.rs @@ -31,7 +31,7 @@ pub(crate) fn target() -> Target { description: Some("ARMv7-A Cortex-A with NuttX".into()), tier: Some(3), host_tools: Some(false), - std: Some(false), + std: Some(true), }, pointer_width: 32, data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".into(), diff --git a/compiler/rustc_target/src/spec/targets/armv7a_nuttx_eabihf.rs b/compiler/rustc_target/src/spec/targets/armv7a_nuttx_eabihf.rs index 40391c9f48e4..f68c11a9c687 100644 --- a/compiler/rustc_target/src/spec/targets/armv7a_nuttx_eabihf.rs +++ b/compiler/rustc_target/src/spec/targets/armv7a_nuttx_eabihf.rs @@ -31,7 +31,7 @@ pub(crate) fn target() -> Target { description: Some("ARMv7-A Cortex-A with NuttX (hard float)".into()), tier: Some(3), host_tools: Some(false), - std: Some(false), + std: Some(true), }, pointer_width: 32, data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".into(), diff --git a/compiler/rustc_target/src/spec/targets/riscv32imac_unknown_nuttx_elf.rs b/compiler/rustc_target/src/spec/targets/riscv32imac_unknown_nuttx_elf.rs index 31c9180c509c..3eb3d18faf44 100644 --- a/compiler/rustc_target/src/spec/targets/riscv32imac_unknown_nuttx_elf.rs +++ b/compiler/rustc_target/src/spec/targets/riscv32imac_unknown_nuttx_elf.rs @@ -6,9 +6,9 @@ pub(crate) fn target() -> Target { llvm_target: "riscv32".into(), metadata: crate::spec::TargetMetadata { description: None, - tier: None, + tier: Some(3), host_tools: None, - std: None, + std: Some(true), }, pointer_width: 32, arch: "riscv32".into(), diff --git a/compiler/rustc_target/src/spec/targets/riscv32imafc_unknown_nuttx_elf.rs b/compiler/rustc_target/src/spec/targets/riscv32imafc_unknown_nuttx_elf.rs index 08dd3cc2a09d..7864f7f8f9a3 100644 --- a/compiler/rustc_target/src/spec/targets/riscv32imafc_unknown_nuttx_elf.rs +++ b/compiler/rustc_target/src/spec/targets/riscv32imafc_unknown_nuttx_elf.rs @@ -6,9 +6,9 @@ pub(crate) fn target() -> Target { llvm_target: "riscv32".into(), metadata: crate::spec::TargetMetadata { description: None, - tier: None, + tier: Some(3), host_tools: None, - std: None, + std: Some(true), }, pointer_width: 32, arch: "riscv32".into(), diff --git a/compiler/rustc_target/src/spec/targets/riscv32imc_unknown_nuttx_elf.rs b/compiler/rustc_target/src/spec/targets/riscv32imc_unknown_nuttx_elf.rs index e86549806ddb..60d8ec576af6 100644 --- a/compiler/rustc_target/src/spec/targets/riscv32imc_unknown_nuttx_elf.rs +++ b/compiler/rustc_target/src/spec/targets/riscv32imc_unknown_nuttx_elf.rs @@ -6,9 +6,9 @@ pub(crate) fn target() -> Target { llvm_target: "riscv32".into(), metadata: crate::spec::TargetMetadata { description: None, - tier: None, + tier: Some(3), host_tools: None, - std: None, + std: Some(true), }, pointer_width: 32, arch: "riscv32".into(), diff --git a/compiler/rustc_target/src/spec/targets/riscv64gc_unknown_nuttx_elf.rs b/compiler/rustc_target/src/spec/targets/riscv64gc_unknown_nuttx_elf.rs index c389759aecd2..2cbb8c19b849 100644 --- a/compiler/rustc_target/src/spec/targets/riscv64gc_unknown_nuttx_elf.rs +++ b/compiler/rustc_target/src/spec/targets/riscv64gc_unknown_nuttx_elf.rs @@ -8,9 +8,9 @@ pub(crate) fn target() -> Target { data_layout: "e-m:e-p:64:64-i64:64-i128:128-n32:64-S128".into(), metadata: crate::spec::TargetMetadata { description: None, - tier: None, + tier: Some(3), host_tools: None, - std: None, + std: Some(true), }, llvm_target: "riscv64".into(), pointer_width: 64, diff --git a/compiler/rustc_target/src/spec/targets/riscv64imac_unknown_nuttx_elf.rs b/compiler/rustc_target/src/spec/targets/riscv64imac_unknown_nuttx_elf.rs index 9c1816655811..306b23d27876 100644 --- a/compiler/rustc_target/src/spec/targets/riscv64imac_unknown_nuttx_elf.rs +++ b/compiler/rustc_target/src/spec/targets/riscv64imac_unknown_nuttx_elf.rs @@ -8,9 +8,9 @@ pub(crate) fn target() -> Target { data_layout: "e-m:e-p:64:64-i64:64-i128:128-n32:64-S128".into(), metadata: crate::spec::TargetMetadata { description: None, - tier: None, + tier: Some(3), host_tools: None, - std: None, + std: Some(true), }, llvm_target: "riscv64".into(), pointer_width: 64, diff --git a/compiler/rustc_target/src/spec/targets/thumbv6m_nuttx_eabi.rs b/compiler/rustc_target/src/spec/targets/thumbv6m_nuttx_eabi.rs index 5799bbf551f8..dcf98acc41f8 100644 --- a/compiler/rustc_target/src/spec/targets/thumbv6m_nuttx_eabi.rs +++ b/compiler/rustc_target/src/spec/targets/thumbv6m_nuttx_eabi.rs @@ -7,9 +7,9 @@ pub(crate) fn target() -> Target { llvm_target: "thumbv6m-none-eabi".into(), metadata: crate::spec::TargetMetadata { description: None, - tier: None, + tier: Some(3), host_tools: None, - std: None, + std: Some(true), }, pointer_width: 32, data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".into(), @@ -22,12 +22,9 @@ pub(crate) fn target() -> Target { llvm_floatabi: Some(FloatAbi::Soft), // The ARMv6-M architecture doesn't support unaligned loads/stores so we disable them // with +strict-align. - // Also force-enable 32-bit atomics, which allows the use of atomic load/store only. - // The resulting atomics are ABI incompatible with atomics backed by libatomic. - features: "+strict-align,+atomics-32".into(), - // There are no atomic CAS instructions available in the instruction set of the ARMv6-M - // architecture - atomic_cas: false, + // The ARMv6-M doesn't support hardware atomic operations, use atomic builtins instead. + features: "+strict-align".into(), + max_atomic_width: Some(32), ..base::thumb::opts() }, } diff --git a/compiler/rustc_target/src/spec/targets/thumbv7a_nuttx_eabi.rs b/compiler/rustc_target/src/spec/targets/thumbv7a_nuttx_eabi.rs index 7fd22602e562..b5cb393f4b00 100644 --- a/compiler/rustc_target/src/spec/targets/thumbv7a_nuttx_eabi.rs +++ b/compiler/rustc_target/src/spec/targets/thumbv7a_nuttx_eabi.rs @@ -11,9 +11,9 @@ pub(crate) fn target() -> Target { llvm_target: "thumbv7a-none-eabi".into(), metadata: crate::spec::TargetMetadata { description: None, - tier: None, + tier: Some(3), host_tools: None, - std: None, + std: Some(true), }, pointer_width: 32, data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".into(), diff --git a/compiler/rustc_target/src/spec/targets/thumbv7a_nuttx_eabihf.rs b/compiler/rustc_target/src/spec/targets/thumbv7a_nuttx_eabihf.rs index d3148c53a829..1aa44a8cc939 100644 --- a/compiler/rustc_target/src/spec/targets/thumbv7a_nuttx_eabihf.rs +++ b/compiler/rustc_target/src/spec/targets/thumbv7a_nuttx_eabihf.rs @@ -14,9 +14,9 @@ pub(crate) fn target() -> Target { llvm_target: "thumbv7a-none-eabihf".into(), metadata: crate::spec::TargetMetadata { description: None, - tier: None, + tier: Some(3), host_tools: None, - std: None, + std: Some(true), }, pointer_width: 32, data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".into(), diff --git a/compiler/rustc_target/src/spec/targets/thumbv7em_nuttx_eabi.rs b/compiler/rustc_target/src/spec/targets/thumbv7em_nuttx_eabi.rs index 536d128590fb..a3bc4013e530 100644 --- a/compiler/rustc_target/src/spec/targets/thumbv7em_nuttx_eabi.rs +++ b/compiler/rustc_target/src/spec/targets/thumbv7em_nuttx_eabi.rs @@ -16,9 +16,9 @@ pub(crate) fn target() -> Target { llvm_target: "thumbv7em-none-eabi".into(), metadata: crate::spec::TargetMetadata { description: None, - tier: None, + tier: Some(3), host_tools: None, - std: None, + std: Some(true), }, pointer_width: 32, data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".into(), diff --git a/compiler/rustc_target/src/spec/targets/thumbv7em_nuttx_eabihf.rs b/compiler/rustc_target/src/spec/targets/thumbv7em_nuttx_eabihf.rs index 35e92b81d87d..14bbe38257d3 100644 --- a/compiler/rustc_target/src/spec/targets/thumbv7em_nuttx_eabihf.rs +++ b/compiler/rustc_target/src/spec/targets/thumbv7em_nuttx_eabihf.rs @@ -15,9 +15,9 @@ pub(crate) fn target() -> Target { llvm_target: "thumbv7em-none-eabihf".into(), metadata: crate::spec::TargetMetadata { description: None, - tier: None, + tier: Some(3), host_tools: None, - std: None, + std: Some(true), }, pointer_width: 32, data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".into(), diff --git a/compiler/rustc_target/src/spec/targets/thumbv7m_nuttx_eabi.rs b/compiler/rustc_target/src/spec/targets/thumbv7m_nuttx_eabi.rs index 320867444ad2..2a77f48a9cd3 100644 --- a/compiler/rustc_target/src/spec/targets/thumbv7m_nuttx_eabi.rs +++ b/compiler/rustc_target/src/spec/targets/thumbv7m_nuttx_eabi.rs @@ -7,9 +7,9 @@ pub(crate) fn target() -> Target { llvm_target: "thumbv7m-none-eabi".into(), metadata: crate::spec::TargetMetadata { description: None, - tier: None, + tier: Some(3), host_tools: None, - std: None, + std: Some(true), }, pointer_width: 32, data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".into(), diff --git a/compiler/rustc_target/src/spec/targets/thumbv8m_base_nuttx_eabi.rs b/compiler/rustc_target/src/spec/targets/thumbv8m_base_nuttx_eabi.rs index 1af01b97666f..25a100e9c7e5 100644 --- a/compiler/rustc_target/src/spec/targets/thumbv8m_base_nuttx_eabi.rs +++ b/compiler/rustc_target/src/spec/targets/thumbv8m_base_nuttx_eabi.rs @@ -7,9 +7,9 @@ pub(crate) fn target() -> Target { llvm_target: "thumbv8m.base-none-eabi".into(), metadata: crate::spec::TargetMetadata { description: None, - tier: None, + tier: Some(3), host_tools: None, - std: None, + std: Some(true), }, pointer_width: 32, data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".into(), diff --git a/compiler/rustc_target/src/spec/targets/thumbv8m_main_nuttx_eabi.rs b/compiler/rustc_target/src/spec/targets/thumbv8m_main_nuttx_eabi.rs index 661d74217adf..0bfe2b32ad4a 100644 --- a/compiler/rustc_target/src/spec/targets/thumbv8m_main_nuttx_eabi.rs +++ b/compiler/rustc_target/src/spec/targets/thumbv8m_main_nuttx_eabi.rs @@ -8,9 +8,9 @@ pub(crate) fn target() -> Target { llvm_target: "thumbv8m.main-none-eabi".into(), metadata: crate::spec::TargetMetadata { description: None, - tier: None, + tier: Some(3), host_tools: None, - std: None, + std: Some(true), }, pointer_width: 32, data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".into(), diff --git a/compiler/rustc_target/src/spec/targets/thumbv8m_main_nuttx_eabihf.rs b/compiler/rustc_target/src/spec/targets/thumbv8m_main_nuttx_eabihf.rs index 484d35bfc202..9f75f23aa93e 100644 --- a/compiler/rustc_target/src/spec/targets/thumbv8m_main_nuttx_eabihf.rs +++ b/compiler/rustc_target/src/spec/targets/thumbv8m_main_nuttx_eabihf.rs @@ -8,9 +8,9 @@ pub(crate) fn target() -> Target { llvm_target: "thumbv8m.main-none-eabihf".into(), metadata: crate::spec::TargetMetadata { description: None, - tier: None, + tier: Some(3), host_tools: None, - std: None, + std: Some(true), }, pointer_width: 32, data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".into(), diff --git a/src/doc/rustc/src/platform-support.md b/src/doc/rustc/src/platform-support.md index c964c29768f9..8227dfa043e3 100644 --- a/src/doc/rustc/src/platform-support.md +++ b/src/doc/rustc/src/platform-support.md @@ -262,7 +262,7 @@ target | std | host | notes [`aarch64-unknown-nto-qnx710`](platform-support/nto-qnx.md) | ✓ | | ARM64 QNX Neutrino 7.1 RTOS with default network stack (io-pkt) | [`aarch64-unknown-nto-qnx710_iosock`](platform-support/nto-qnx.md) | ✓ | | ARM64 QNX Neutrino 7.1 RTOS with new network stack (io-sock) | [`aarch64-unknown-nto-qnx800`](platform-support/nto-qnx.md) | ✓ | | ARM64 QNX Neutrino 8.0 RTOS | -[`aarch64-unknown-nuttx`](platform-support/nuttx.md) | * | | ARM64 with NuttX +[`aarch64-unknown-nuttx`](platform-support/nuttx.md) | ✓ | | ARM64 with NuttX [`aarch64-unknown-openbsd`](platform-support/openbsd.md) | ✓ | ✓ | ARM64 OpenBSD [`aarch64-unknown-redox`](platform-support/redox.md) | ✓ | | ARM64 Redox OS [`aarch64-unknown-teeos`](platform-support/aarch64-unknown-teeos.md) | ? | | ARM64 TEEOS | @@ -298,8 +298,8 @@ target | std | host | notes [`armv7k-apple-watchos`](platform-support/apple-watchos.md) | ✓ | | Armv7-A Apple WatchOS [`armv7s-apple-ios`](platform-support/apple-ios.md) | ✓ | | Armv7-A Apple-A6 Apple iOS [`armv8r-none-eabihf`](platform-support/armv8r-none-eabihf.md) | * | | Bare Armv8-R, hardfloat -[`armv7a-nuttx-eabi`](platform-support/nuttx.md) | * | | ARMv7-A with NuttX -[`armv7a-nuttx-eabihf`](platform-support/nuttx.md) | * | | ARMv7-A with NuttX, hardfloat +[`armv7a-nuttx-eabi`](platform-support/nuttx.md) | ✓ | | ARMv7-A with NuttX +[`armv7a-nuttx-eabihf`](platform-support/nuttx.md) | ✓ | | ARMv7-A with NuttX, hardfloat `avr-unknown-gnu-atmega328` | * | | AVR. Requires `-Z build-std=core` `bpfeb-unknown-none` | * | | BPF (big endian) `bpfel-unknown-none` | * | | BPF (little endian) @@ -369,21 +369,21 @@ target | std | host | notes [`riscv32im-risc0-zkvm-elf`](platform-support/riscv32im-risc0-zkvm-elf.md) | ? | | RISC Zero's zero-knowledge Virtual Machine (RV32IM ISA) [`riscv32ima-unknown-none-elf`](platform-support/riscv32-unknown-none-elf.md) | * | | Bare RISC-V (RV32IMA ISA) [`riscv32imac-esp-espidf`](platform-support/esp-idf.md) | ✓ | | RISC-V ESP-IDF -[`riscv32imac-unknown-nuttx-elf`](platform-support/nuttx.md) | * | | RISC-V 32bit with NuttX +[`riscv32imac-unknown-nuttx-elf`](platform-support/nuttx.md) | ✓ | | RISC-V 32bit with NuttX [`riscv32imac-unknown-xous-elf`](platform-support/riscv32imac-unknown-xous-elf.md) | ? | | RISC-V Xous (RV32IMAC ISA) [`riscv32imafc-esp-espidf`](platform-support/esp-idf.md) | ✓ | | RISC-V ESP-IDF -[`riscv32imafc-unknown-nuttx-elf`](platform-support/nuttx.md) | * | | RISC-V 32bit with NuttX +[`riscv32imafc-unknown-nuttx-elf`](platform-support/nuttx.md) | ✓ | | RISC-V 32bit with NuttX [`riscv32imc-esp-espidf`](platform-support/esp-idf.md) | ✓ | | RISC-V ESP-IDF -[`riscv32imc-unknown-nuttx-elf`](platform-support/nuttx.md) | * | | RISC-V 32bit with NuttX +[`riscv32imc-unknown-nuttx-elf`](platform-support/nuttx.md) | ✓ | | RISC-V 32bit with NuttX [`riscv64-linux-android`](platform-support/android.md) | ? | | RISC-V 64-bit Android [`riscv64-wrs-vxworks`](platform-support/vxworks.md) | ✓ | | `riscv64gc-unknown-freebsd` | ? | | RISC-V FreeBSD `riscv64gc-unknown-fuchsia` | ? | | RISC-V Fuchsia [`riscv64gc-unknown-hermit`](platform-support/hermit.md) | ✓ | | RISC-V Hermit [`riscv64gc-unknown-netbsd`](platform-support/netbsd.md) | ✓ | ✓ | RISC-V NetBSD -[`riscv64gc-unknown-nuttx-elf`](platform-support/nuttx.md) | * | | RISC-V 64bit with NuttX +[`riscv64gc-unknown-nuttx-elf`](platform-support/nuttx.md) | ✓ | | RISC-V 64bit with NuttX [`riscv64gc-unknown-openbsd`](platform-support/openbsd.md) | ✓ | ✓ | OpenBSD/riscv64 -[`riscv64imac-unknown-nuttx-elf`](platform-support/nuttx.md) | * | | RISC-V 64bit with NuttX +[`riscv64imac-unknown-nuttx-elf`](platform-support/nuttx.md) | ✓ | | RISC-V 64bit with NuttX [`s390x-unknown-linux-musl`](platform-support/s390x-unknown-linux-musl.md) | ✓ | | S390x Linux (kernel 3.2, musl 1.2.3) `sparc-unknown-linux-gnu` | ✓ | | 32-bit SPARC Linux [`sparc-unknown-none-elf`](./platform-support/sparc-unknown-none-elf.md) | * | | Bare 32-bit SPARC V7+ @@ -391,18 +391,18 @@ target | std | host | notes [`sparc64-unknown-openbsd`](platform-support/openbsd.md) | ✓ | ✓ | OpenBSD/sparc64 [`thumbv4t-none-eabi`](platform-support/armv4t-none-eabi.md) | * | | Thumb-mode Bare Armv4T [`thumbv5te-none-eabi`](platform-support/armv5te-none-eabi.md) | * | | Thumb-mode Bare Armv5TE -[`thumbv6m-nuttx-eabi`](platform-support/nuttx.md) | * | | ARMv6M with NuttX +[`thumbv6m-nuttx-eabi`](platform-support/nuttx.md) | ✓ | | ARMv6M with NuttX `thumbv7a-pc-windows-msvc` | | | [`thumbv7a-uwp-windows-msvc`](platform-support/uwp-windows-msvc.md) | | | -[`thumbv7a-nuttx-eabi`](platform-support/nuttx.md) | * | | ARMv7-A with NuttX -[`thumbv7a-nuttx-eabihf`](platform-support/nuttx.md) | * | | ARMv7-A with NuttX, hardfloat -[`thumbv7em-nuttx-eabi`](platform-support/nuttx.md) | * | | ARMv7EM with NuttX -[`thumbv7em-nuttx-eabihf`](platform-support/nuttx.md) | * | | ARMv7EM with NuttX, hardfloat -[`thumbv7m-nuttx-eabi`](platform-support/nuttx.md) | * | | ARMv7M with NuttX +[`thumbv7a-nuttx-eabi`](platform-support/nuttx.md) | ✓ | | ARMv7-A with NuttX +[`thumbv7a-nuttx-eabihf`](platform-support/nuttx.md) | ✓ | | ARMv7-A with NuttX, hardfloat +[`thumbv7em-nuttx-eabi`](platform-support/nuttx.md) | ✓ | | ARMv7EM with NuttX +[`thumbv7em-nuttx-eabihf`](platform-support/nuttx.md) | ✓ | | ARMv7EM with NuttX, hardfloat +[`thumbv7m-nuttx-eabi`](platform-support/nuttx.md) | ✓ | | ARMv7M with NuttX `thumbv7neon-unknown-linux-musleabihf` | ? | | Thumb2-mode Armv7-A Linux with NEON, musl 1.2.3 -[`thumbv8m.base-nuttx-eabi`](platform-support/nuttx.md) | * | | ARMv8M Baseline with NuttX -[`thumbv8m.main-nuttx-eabi`](platform-support/nuttx.md) | * | | ARMv8M Mainline with NuttX -[`thumbv8m.main-nuttx-eabihf`](platform-support/nuttx.md) | * | | ARMv8M Mainline with NuttX, hardfloat +[`thumbv8m.base-nuttx-eabi`](platform-support/nuttx.md) | ✓ | | ARMv8M Baseline with NuttX +[`thumbv8m.main-nuttx-eabi`](platform-support/nuttx.md) | ✓ | | ARMv8M Mainline with NuttX +[`thumbv8m.main-nuttx-eabihf`](platform-support/nuttx.md) | ✓ | | ARMv8M Mainline with NuttX, hardfloat [`wasm64-unknown-unknown`](platform-support/wasm64-unknown-unknown.md) | ? | | WebAssembly [`x86_64-apple-tvos`](platform-support/apple-tvos.md) | ✓ | | x86 64-bit tvOS [`x86_64-apple-watchos-sim`](platform-support/apple-watchos.md) | ✓ | | x86 64-bit Apple WatchOS simulator From ac1c6c50f4a82a34002231d2c1a2a5a007af959f Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Mon, 27 Jan 2025 01:16:12 +0000 Subject: [PATCH 71/81] Use identifiers in diagnostics more often --- .../src/check/compare_impl_item.rs | 2 +- compiler/rustc_hir_analysis/src/check/mod.rs | 4 +-- .../src/coherence/builtin.rs | 2 +- .../src/coherence/orphan.rs | 6 ++-- compiler/rustc_hir_analysis/src/collect.rs | 11 +++---- .../src/collect/type_of/opaque.rs | 4 +-- compiler/rustc_hir_analysis/src/errors.rs | 32 +++++++++---------- .../rustc_hir_analysis/src/impl_wf_check.rs | 4 +-- compiler/rustc_lint/src/dangling.rs | 2 +- compiler/rustc_lint/src/lints.rs | 4 +-- compiler/rustc_lint/src/noop_method_call.rs | 2 +- compiler/rustc_middle/src/ty/mod.rs | 9 ++++++ compiler/rustc_mir_build/src/errors.rs | 6 ++-- .../src/thir/pattern/check_match.rs | 6 ++-- compiler/rustc_parse/src/errors.rs | 2 +- compiler/rustc_parse/src/parser/expr.rs | 2 +- compiler/rustc_resolve/src/diagnostics.rs | 2 +- compiler/rustc_resolve/src/errors.rs | 16 +++++----- compiler/rustc_resolve/src/late.rs | 13 ++++---- compiler/rustc_resolve/src/lib.rs | 14 ++++---- .../traits/on_unimplemented.rs | 12 ++++--- 21 files changed, 83 insertions(+), 72 deletions(-) diff --git a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs index dbc5c634c455..d2ab98bae891 100644 --- a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs +++ b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs @@ -2362,7 +2362,7 @@ fn try_report_async_mismatch<'tcx>( // the right span is a bit difficult. return Err(tcx.sess.dcx().emit_err(MethodShouldReturnFuture { span: tcx.def_span(impl_m.def_id), - method_name: trait_m.name, + method_name: tcx.item_ident(impl_m.def_id), trait_item_span: tcx.hir().span_if_local(trait_m.def_id), })); } diff --git a/compiler/rustc_hir_analysis/src/check/mod.rs b/compiler/rustc_hir_analysis/src/check/mod.rs index 92b18c80fd82..69b4aa47ebad 100644 --- a/compiler/rustc_hir_analysis/src/check/mod.rs +++ b/compiler/rustc_hir_analysis/src/check/mod.rs @@ -197,7 +197,7 @@ fn maybe_check_static_with_link_section(tcx: TyCtxt<'_>, id: LocalDefId) { fn report_forbidden_specialization(tcx: TyCtxt<'_>, impl_item: DefId, parent_impl: DefId) { let span = tcx.def_span(impl_item); - let ident = tcx.item_name(impl_item); + let ident = tcx.item_ident(impl_item); let err = match tcx.span_of_impl(parent_impl) { Ok(sp) => errors::ImplNotMarkedDefault::Ok { span, ident, ok_label: sp }, @@ -297,7 +297,7 @@ fn default_body_is_unstable( reason: Option, issue: Option>, ) { - let missing_item_name = tcx.associated_item(item_did).name; + let missing_item_name = tcx.item_ident(item_did); let (mut some_note, mut none_note, mut reason_str) = (false, false, String::new()); match reason { Some(r) => { diff --git a/compiler/rustc_hir_analysis/src/coherence/builtin.rs b/compiler/rustc_hir_analysis/src/coherence/builtin.rs index b43a808ccdc1..27a7c2ea530f 100644 --- a/compiler/rustc_hir_analysis/src/coherence/builtin.rs +++ b/compiler/rustc_hir_analysis/src/coherence/builtin.rs @@ -292,7 +292,7 @@ fn visit_implementation_of_dispatch_from_dyn(checker: &Checker<'_>) -> Result<() res = Err(tcx.dcx().emit_err(errors::DispatchFromDynZST { span, - name: field.name, + name: field.ident(tcx), ty: ty_a, })); diff --git a/compiler/rustc_hir_analysis/src/coherence/orphan.rs b/compiler/rustc_hir_analysis/src/coherence/orphan.rs index d17ee86ba667..dbf7a7378f5a 100644 --- a/compiler/rustc_hir_analysis/src/coherence/orphan.rs +++ b/compiler/rustc_hir_analysis/src/coherence/orphan.rs @@ -465,8 +465,8 @@ fn emit_orphan_check_error<'tcx>( traits::OrphanCheckErr::UncoveredTyParams(UncoveredTyParams { uncovered, local_ty }) => { let mut reported = None; for param_def_id in uncovered { - let span = tcx.def_ident_span(param_def_id).unwrap(); - let name = tcx.item_name(param_def_id); + let name = tcx.item_ident(param_def_id); + let span = name.span; reported.get_or_insert(match local_ty { Some(local_type) => tcx.dcx().emit_err(errors::TyParamFirstLocal { @@ -492,7 +492,7 @@ fn lint_uncovered_ty_params<'tcx>( for param_def_id in uncovered { let span = tcx.def_ident_span(param_def_id).unwrap(); - let name = tcx.item_name(param_def_id); + let name = tcx.item_ident(param_def_id); match local_ty { Some(local_type) => tcx.emit_node_span_lint( diff --git a/compiler/rustc_hir_analysis/src/collect.rs b/compiler/rustc_hir_analysis/src/collect.rs index c517d25fcbfc..447050ea7d20 100644 --- a/compiler/rustc_hir_analysis/src/collect.rs +++ b/compiler/rustc_hir_analysis/src/collect.rs @@ -928,7 +928,7 @@ fn lower_enum_variant_types(tcx: TyCtxt<'_>, def_id: DefId) { tcx.dcx().emit_err(errors::EnumDiscriminantOverflowed { span, discr: prev_discr.unwrap().to_string(), - item_name: tcx.item_name(variant.def_id), + item_name: tcx.item_ident(variant.def_id), wrapped_discr: wrapped_discr.to_string(), }); None @@ -990,11 +990,10 @@ impl<'tcx> FieldUniquenessCheckContext<'tcx> { } /// Check if a given field `ident` declared at `field_decl` has been declared elsewhere before. - fn check_field_decl(&mut self, ident: Ident, field_decl: FieldDeclSpan) { + fn check_field_decl(&mut self, field_name: Ident, field_decl: FieldDeclSpan) { use FieldDeclSpan::*; - let field_name = ident.name; - let ident = ident.normalize_to_macros_2_0(); - match (field_decl, self.seen_fields.get(&ident).copied()) { + let field_name = field_name.normalize_to_macros_2_0(); + match (field_decl, self.seen_fields.get(&field_name).copied()) { (NotNested(span), Some(NotNested(prev_span))) => { self.tcx.dcx().emit_err(errors::FieldAlreadyDeclared::NotNested { field_name, @@ -1035,7 +1034,7 @@ impl<'tcx> FieldUniquenessCheckContext<'tcx> { }); } (field_decl, None) => { - self.seen_fields.insert(ident, field_decl); + self.seen_fields.insert(field_name, field_decl); } } } diff --git a/compiler/rustc_hir_analysis/src/collect/type_of/opaque.rs b/compiler/rustc_hir_analysis/src/collect/type_of/opaque.rs index d1a1e36c1d5a..e2b9fe0f9f72 100644 --- a/compiler/rustc_hir_analysis/src/collect/type_of/opaque.rs +++ b/compiler/rustc_hir_analysis/src/collect/type_of/opaque.rs @@ -55,7 +55,7 @@ pub(super) fn find_opaque_ty_constraints_for_impl_trait_in_assoc_type( } else { let reported = tcx.dcx().emit_err(UnconstrainedOpaqueType { span: tcx.def_span(def_id), - name: tcx.item_name(parent_def_id.to_def_id()), + name: tcx.item_ident(parent_def_id.to_def_id()), what: "impl", }); Ty::new_error(tcx, reported) @@ -136,7 +136,7 @@ pub(super) fn find_opaque_ty_constraints_for_tait(tcx: TyCtxt<'_>, def_id: Local } let reported = tcx.dcx().emit_err(UnconstrainedOpaqueType { span: tcx.def_span(def_id), - name: tcx.item_name(parent_def_id.to_def_id()), + name: tcx.item_ident(parent_def_id.to_def_id()), what: match tcx.hir_node(scope) { _ if scope == hir::CRATE_HIR_ID => "module", Node::Item(hir::Item { kind: hir::ItemKind::Mod(_), .. }) => "module", diff --git a/compiler/rustc_hir_analysis/src/errors.rs b/compiler/rustc_hir_analysis/src/errors.rs index a0f365142bae..1dcea5d03353 100644 --- a/compiler/rustc_hir_analysis/src/errors.rs +++ b/compiler/rustc_hir_analysis/src/errors.rs @@ -217,7 +217,7 @@ pub(crate) struct DropImplOnWrongItem { pub(crate) enum FieldAlreadyDeclared { #[diag(hir_analysis_field_already_declared, code = E0124)] NotNested { - field_name: Symbol, + field_name: Ident, #[primary_span] #[label] span: Span, @@ -226,7 +226,7 @@ pub(crate) enum FieldAlreadyDeclared { }, #[diag(hir_analysis_field_already_declared_current_nested)] CurrentNested { - field_name: Symbol, + field_name: Ident, #[primary_span] #[label] span: Span, @@ -239,7 +239,7 @@ pub(crate) enum FieldAlreadyDeclared { }, #[diag(hir_analysis_field_already_declared_previous_nested)] PreviousNested { - field_name: Symbol, + field_name: Ident, #[primary_span] #[label] span: Span, @@ -252,7 +252,7 @@ pub(crate) enum FieldAlreadyDeclared { }, #[diag(hir_analysis_field_already_declared_both_nested)] BothNested { - field_name: Symbol, + field_name: Ident, #[primary_span] #[label] span: Span, @@ -418,7 +418,7 @@ pub(crate) struct ValueOfAssociatedStructAlreadySpecified { pub(crate) struct UnconstrainedOpaqueType { #[primary_span] pub span: Span, - pub name: Symbol, + pub name: Ident, pub what: &'static str, } @@ -802,7 +802,7 @@ pub(crate) struct EnumDiscriminantOverflowed { #[label] pub span: Span, pub discr: String, - pub item_name: Symbol, + pub item_name: Ident, pub wrapped_discr: String, } @@ -893,7 +893,7 @@ pub(crate) enum ImplNotMarkedDefault { span: Span, #[label(hir_analysis_ok_label)] ok_label: Span, - ident: Symbol, + ident: Ident, }, #[diag(hir_analysis_impl_not_marked_default_err, code = E0520)] #[note] @@ -901,7 +901,7 @@ pub(crate) enum ImplNotMarkedDefault { #[primary_span] span: Span, cname: Symbol, - ident: Symbol, + ident: Ident, }, } @@ -977,7 +977,7 @@ pub(crate) struct MissingTraitItemUnstable { pub some_note: bool, #[note(hir_analysis_none_note)] pub none_note: bool, - pub missing_item_name: Symbol, + pub missing_item_name: Ident, pub feature: Symbol, pub reason: String, } @@ -1249,7 +1249,7 @@ pub(crate) struct InherentNominal { pub(crate) struct DispatchFromDynZST<'a> { #[primary_span] pub span: Span, - pub name: Symbol, + pub name: Ident, pub ty: Ty<'a>, } @@ -1389,7 +1389,7 @@ pub(crate) struct TyParamFirstLocal<'tcx> { pub span: Span, #[note(hir_analysis_case_note)] pub note: (), - pub param: Symbol, + pub param: Ident, pub local_type: Ty<'tcx>, } @@ -1401,7 +1401,7 @@ pub(crate) struct TyParamFirstLocalLint<'tcx> { pub span: Span, #[note(hir_analysis_case_note)] pub note: (), - pub param: Symbol, + pub param: Ident, pub local_type: Ty<'tcx>, } @@ -1414,7 +1414,7 @@ pub(crate) struct TyParamSome { pub span: Span, #[note(hir_analysis_only_note)] pub note: (), - pub param: Symbol, + pub param: Ident, } #[derive(LintDiagnostic)] @@ -1425,7 +1425,7 @@ pub(crate) struct TyParamSomeLint { pub span: Span, #[note(hir_analysis_only_note)] pub note: (), - pub param: Symbol, + pub param: Ident, } #[derive(Diagnostic)] @@ -1533,7 +1533,7 @@ pub(crate) struct UnsupportedDelegation<'a> { pub(crate) struct MethodShouldReturnFuture { #[primary_span] pub span: Span, - pub method_name: Symbol, + pub method_name: Ident, #[note] pub trait_item_span: Option, } @@ -1585,7 +1585,7 @@ pub(crate) struct UnconstrainedGenericParameter { #[primary_span] #[label] pub span: Span, - pub param_name: Symbol, + pub param_name: Ident, pub param_def_kind: &'static str, #[note(hir_analysis_const_param_note)] pub const_param_note: bool, diff --git a/compiler/rustc_hir_analysis/src/impl_wf_check.rs b/compiler/rustc_hir_analysis/src/impl_wf_check.rs index 42034736ad67..fd5a7089b4cf 100644 --- a/compiler/rustc_hir_analysis/src/impl_wf_check.rs +++ b/compiler/rustc_hir_analysis/src/impl_wf_check.rs @@ -152,7 +152,7 @@ pub(crate) fn enforce_impl_lifetime_params_are_constrained( { let mut diag = tcx.dcx().create_err(UnconstrainedGenericParameter { span: tcx.def_span(param.def_id), - param_name: param.name, + param_name: tcx.item_ident(param.def_id), param_def_kind: tcx.def_descr(param.def_id), const_param_note: false, const_param_note2: false, @@ -223,7 +223,7 @@ pub(crate) fn enforce_impl_non_lifetime_params_are_constrained( let const_param_note = matches!(param.kind, ty::GenericParamDefKind::Const { .. }); let mut diag = tcx.dcx().create_err(UnconstrainedGenericParameter { span: tcx.def_span(param.def_id), - param_name: param.name, + param_name: tcx.item_ident(param.def_id), param_def_kind: tcx.def_descr(param.def_id), const_param_note, const_param_note2: const_param_note, diff --git a/compiler/rustc_lint/src/dangling.rs b/compiler/rustc_lint/src/dangling.rs index 98b717a30706..fd6b3e90adab 100644 --- a/compiler/rustc_lint/src/dangling.rs +++ b/compiler/rustc_lint/src/dangling.rs @@ -141,7 +141,7 @@ fn lint_expr(cx: &LateContext<'_>, expr: &Expr<'_>) { expr.hir_id, method.ident.span, DanglingPointersFromTemporaries { - callee: method.ident.name, + callee: method.ident, ty, ptr_span: method.ident.span, temporary_span: receiver.span, diff --git a/compiler/rustc_lint/src/lints.rs b/compiler/rustc_lint/src/lints.rs index 3163bc8a300a..e90d6fe2061e 100644 --- a/compiler/rustc_lint/src/lints.rs +++ b/compiler/rustc_lint/src/lints.rs @@ -1132,7 +1132,7 @@ pub(crate) struct IgnoredUnlessCrateSpecified<'a> { #[help(lint_help_visit)] // FIXME: put #[primary_span] on `ptr_span` once it does not cause conflicts pub(crate) struct DanglingPointersFromTemporaries<'tcx> { - pub callee: Symbol, + pub callee: Ident, pub ty: Ty<'tcx>, #[label(lint_label_ptr)] pub ptr_span: Span, @@ -1333,7 +1333,7 @@ pub(crate) enum NonUpperCaseGlobalSub { #[diag(lint_noop_method_call)] #[note] pub(crate) struct NoopMethodCallDiag<'a> { - pub method: Symbol, + pub method: Ident, pub orig_ty: Ty<'a>, pub trait_: Symbol, #[suggestion(code = "", applicability = "machine-applicable")] diff --git a/compiler/rustc_lint/src/noop_method_call.rs b/compiler/rustc_lint/src/noop_method_call.rs index fa519281be53..790ef910b041 100644 --- a/compiler/rustc_lint/src/noop_method_call.rs +++ b/compiler/rustc_lint/src/noop_method_call.rs @@ -129,7 +129,7 @@ impl<'tcx> LateLintPass<'tcx> for NoopMethodCall { _ => None, }; cx.emit_span_lint(NOOP_METHOD_CALL, span, NoopMethodCallDiag { - method: call.ident.name, + method: call.ident, orig_ty, trait_, label: span, diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index ca70ae794c53..8cd632790a8a 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -1596,6 +1596,15 @@ impl<'tcx> TyCtxt<'tcx> { Some(Ident::new(def, span)) } + /// Look up the name and span of a definition. + /// + /// See [`item_name`][Self::item_name] for more information. + pub fn item_ident(self, def_id: DefId) -> Ident { + self.opt_item_ident(def_id).unwrap_or_else(|| { + bug!("item_ident: no name for {:?}", self.def_path(def_id)); + }) + } + pub fn opt_associated_item(self, def_id: DefId) -> Option { if let DefKind::AssocConst | DefKind::AssocFn | DefKind::AssocTy = self.def_kind(def_id) { Some(self.associated_item(def_id)) diff --git a/compiler/rustc_mir_build/src/errors.rs b/compiler/rustc_mir_build/src/errors.rs index c3bf5868eecd..1f87bf0dbbbd 100644 --- a/compiler/rustc_mir_build/src/errors.rs +++ b/compiler/rustc_mir_build/src/errors.rs @@ -7,7 +7,7 @@ use rustc_macros::{Diagnostic, LintDiagnostic, Subdiagnostic}; use rustc_middle::ty::{self, Ty}; use rustc_pattern_analysis::errors::Uncovered; use rustc_pattern_analysis::rustc::RustcPatCtxt; -use rustc_span::{Span, Symbol}; +use rustc_span::{Ident, Span, Symbol}; use crate::fluent_generated as fluent; @@ -753,7 +753,7 @@ pub(crate) struct BindingsWithVariantName { #[suggestion(code = "{ty_path}::{name}", applicability = "machine-applicable")] pub(crate) suggestion: Option, pub(crate) ty_path: String, - pub(crate) name: Symbol, + pub(crate) name: Ident, } #[derive(LintDiagnostic)] @@ -797,7 +797,7 @@ pub(crate) struct BorrowOfMovedValue { pub(crate) binding_span: Span, #[label(mir_build_value_borrowed_label)] pub(crate) conflicts_ref: Vec, - pub(crate) name: Symbol, + pub(crate) name: Ident, pub(crate) ty: String, #[suggestion(code = "ref ", applicability = "machine-applicable")] pub(crate) suggest_borrowing: Option, diff --git a/compiler/rustc_mir_build/src/thir/pattern/check_match.rs b/compiler/rustc_mir_build/src/thir/pattern/check_match.rs index d8b04398d9a5..e0a1117f905c 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/check_match.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/check_match.rs @@ -25,7 +25,7 @@ use rustc_session::lint::builtin::{ }; use rustc_span::edit_distance::find_best_match_for_name; use rustc_span::hygiene::DesugaringKind; -use rustc_span::{Span, sym}; +use rustc_span::{Ident, Span, sym}; use rustc_trait_selection::infer::InferCtxtExt; use tracing::instrument; @@ -800,7 +800,7 @@ fn check_borrow_conflicts_in_at_patterns<'tcx>(cx: &MatchVisitor<'_, 'tcx>, pat: sess.dcx().emit_err(BorrowOfMovedValue { binding_span: pat.span, conflicts_ref, - name, + name: Ident::new(name, pat.span), ty, suggest_borrowing: Some(pat.span.shrink_to_lo()), has_path: path.is_some(), @@ -908,7 +908,7 @@ fn check_for_bindings_named_same_as_variants( None }, ty_path, - name, + name: Ident::new(name, pat.span), }, ) } diff --git a/compiler/rustc_parse/src/errors.rs b/compiler/rustc_parse/src/errors.rs index f78d9dc2bfc2..50287b706ce8 100644 --- a/compiler/rustc_parse/src/errors.rs +++ b/compiler/rustc_parse/src/errors.rs @@ -3233,7 +3233,7 @@ pub(crate) struct MalformedCfgAttr { pub(crate) struct UnknownBuiltinConstruct { #[primary_span] pub span: Span, - pub name: Symbol, + pub name: Ident, } #[derive(Diagnostic)] diff --git a/compiler/rustc_parse/src/parser/expr.rs b/compiler/rustc_parse/src/parser/expr.rs index 5cd02128287e..a5b73ce4098e 100644 --- a/compiler/rustc_parse/src/parser/expr.rs +++ b/compiler/rustc_parse/src/parser/expr.rs @@ -1958,7 +1958,7 @@ impl<'a> Parser<'a> { } else { let err = self.dcx().create_err(errors::UnknownBuiltinConstruct { span: lo.to(ident.span), - name: ident.name, + name: ident, }); return Err(err); }; diff --git a/compiler/rustc_resolve/src/diagnostics.rs b/compiler/rustc_resolve/src/diagnostics.rs index ccd5b519cb04..8dc752c2cb38 100644 --- a/compiler/rustc_resolve/src/diagnostics.rs +++ b/compiler/rustc_resolve/src/diagnostics.rs @@ -677,7 +677,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { } if could_be_path { let import_suggestions = self.lookup_import_candidates( - Ident::with_dummy_span(name), + name, Namespace::ValueNS, &parent_scope, &|res: Res| { diff --git a/compiler/rustc_resolve/src/errors.rs b/compiler/rustc_resolve/src/errors.rs index 3bfe98f7091b..7eb795034b03 100644 --- a/compiler/rustc_resolve/src/errors.rs +++ b/compiler/rustc_resolve/src/errors.rs @@ -59,7 +59,7 @@ pub(crate) struct NameAlreadyUsedInParameterList { pub(crate) span: Span, #[label(resolve_first_use_of_name)] pub(crate) first_use_span: Span, - pub(crate) name: Symbol, + pub(crate) name: Ident, } #[derive(Diagnostic)] @@ -142,7 +142,7 @@ pub(crate) struct VariableBoundWithDifferentMode { pub(crate) span: Span, #[label(resolve_first_binding_span)] pub(crate) first_binding_span: Span, - pub(crate) variable_name: Symbol, + pub(crate) variable_name: Ident, } #[derive(Diagnostic)] @@ -151,7 +151,7 @@ pub(crate) struct IdentifierBoundMoreThanOnceInParameterList { #[primary_span] #[label] pub(crate) span: Span, - pub(crate) identifier: Symbol, + pub(crate) identifier: Ident, } #[derive(Diagnostic)] @@ -160,7 +160,7 @@ pub(crate) struct IdentifierBoundMoreThanOnceInSamePattern { #[primary_span] #[label] pub(crate) span: Span, - pub(crate) identifier: Symbol, + pub(crate) identifier: Ident, } #[derive(Diagnostic)] @@ -478,7 +478,7 @@ pub(crate) struct TraitImplDuplicate { pub(crate) old_span: Span, #[label(resolve_trait_item_span)] pub(crate) trait_item_span: Span, - pub(crate) name: Symbol, + pub(crate) name: Ident, } #[derive(Diagnostic)] @@ -976,7 +976,7 @@ pub(crate) struct AttemptToDefineBuiltinMacroTwice { pub(crate) struct VariableIsNotBoundInAllPatterns { #[primary_span] pub(crate) multispan: MultiSpan, - pub(crate) name: Symbol, + pub(crate) name: Ident, } #[derive(Subdiagnostic, Debug, Clone)] @@ -984,7 +984,7 @@ pub(crate) struct VariableIsNotBoundInAllPatterns { pub(crate) struct PatternDoesntBindName { #[primary_span] pub(crate) span: Span, - pub(crate) name: Symbol, + pub(crate) name: Ident, } #[derive(Subdiagnostic, Debug, Clone)] @@ -1260,7 +1260,7 @@ pub(crate) struct TraitImplMismatch { #[primary_span] #[label] pub(crate) span: Span, - pub(crate) name: Symbol, + pub(crate) name: Ident, pub(crate) kind: &'static str, pub(crate) trait_path: String, #[label(resolve_trait_impl_mismatch_label_item)] diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs index 8bd40ed3a73b..68d3351f174c 100644 --- a/compiler/rustc_resolve/src/late.rs +++ b/compiler/rustc_resolve/src/late.rs @@ -2835,7 +2835,7 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { match seen_bindings.entry(ident) { Entry::Occupied(entry) => { let span = *entry.get(); - let err = ResolutionError::NameAlreadyUsedInParameterList(ident.name, span); + let err = ResolutionError::NameAlreadyUsedInParameterList(ident, span); self.report_error(param.ident.span, err); let rib = match param.kind { GenericParamKind::Lifetime => { @@ -3422,7 +3422,7 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { match seen_trait_items.entry(id_in_trait) { Entry::Occupied(entry) => { self.report_error(span, ResolutionError::TraitImplDuplicate { - name: ident.name, + name: ident, old_span: *entry.get(), trait_item_span: binding.span, }); @@ -3457,7 +3457,7 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { }; let trait_path = path_names_to_string(path); self.report_error(span, ResolutionError::TraitImplMismatch { - name: ident.name, + name: ident, kind, code, trait_path, @@ -3640,9 +3640,8 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { .filter(|(_, pat)| pat.id != pat_outer.id) .flat_map(|(map, _)| map); - for (key, binding_inner) in inners { - let name = key.name; - match map_outer.get(key) { + for (&name, binding_inner) in inners { + match map_outer.get(&name) { None => { // The inner binding is missing in the outer. let binding_error = @@ -3880,7 +3879,7 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { // `Variant(a, a)`: _ => IdentifierBoundMoreThanOnceInSamePattern, }; - self.report_error(ident.span, error(ident.name)); + self.report_error(ident.span, error(ident)); } // Record as bound if it's valid: diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs index 3b18e480be44..04144eb616fa 100644 --- a/compiler/rustc_resolve/src/lib.rs +++ b/compiler/rustc_resolve/src/lib.rs @@ -214,7 +214,7 @@ enum Used { #[derive(Debug)] struct BindingError { - name: Symbol, + name: Ident, origin: BTreeSet, target: BTreeSet, could_be_path: bool, @@ -226,7 +226,7 @@ enum ResolutionError<'ra> { GenericParamsFromOuterItem(Res, HasGenericParams, DefKind), /// Error E0403: the name is already used for a type or const parameter in this generic /// parameter list. - NameAlreadyUsedInParameterList(Symbol, Span), + NameAlreadyUsedInParameterList(Ident, Span), /// Error E0407: method is not a member of trait. MethodNotMemberOfTrait(Ident, String, Option), /// Error E0437: type is not a member of trait. @@ -236,11 +236,11 @@ enum ResolutionError<'ra> { /// Error E0408: variable `{}` is not bound in all patterns. VariableNotBoundInPattern(BindingError, ParentScope<'ra>), /// Error E0409: variable `{}` is bound in inconsistent ways within the same match arm. - VariableBoundWithDifferentMode(Symbol, Span), + VariableBoundWithDifferentMode(Ident, Span), /// Error E0415: identifier is bound more than once in this parameter list. - IdentifierBoundMoreThanOnceInParameterList(Symbol), + IdentifierBoundMoreThanOnceInParameterList(Ident), /// Error E0416: identifier is bound more than once in the same pattern. - IdentifierBoundMoreThanOnceInSamePattern(Symbol), + IdentifierBoundMoreThanOnceInSamePattern(Ident), /// Error E0426: use of undeclared label. UndeclaredLabel { name: Symbol, suggestion: Option }, /// Error E0429: `self` imports are only allowed within a `{ }` list. @@ -292,14 +292,14 @@ enum ResolutionError<'ra> { UnreachableLabel { name: Symbol, definition_span: Span, suggestion: Option }, /// Error E0323, E0324, E0325: mismatch between trait item and impl item. TraitImplMismatch { - name: Symbol, + name: Ident, kind: &'static str, trait_path: String, trait_item_span: Span, code: ErrCode, }, /// Error E0201: multiple impl items for the same trait item. - TraitImplDuplicate { name: Symbol, trait_item_span: Span, old_span: Span }, + TraitImplDuplicate { name: Ident, trait_item_span: Span, old_span: Span }, /// Inline asm `sym` operand must refer to a `fn` or `static`. InvalidAsmSym, /// `self` used instead of `Self` in a generic parameter diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/on_unimplemented.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/on_unimplemented.rs index 2d932e36470e..4e0b097db4c6 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/traits/on_unimplemented.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/on_unimplemented.rs @@ -13,7 +13,7 @@ use rustc_middle::ty::print::PrintTraitRefExt as _; use rustc_middle::ty::{self, GenericArgsRef, GenericParamDefKind, TyCtxt}; use rustc_parse_format::{ParseMode, Parser, Piece, Position}; use rustc_session::lint::builtin::UNKNOWN_OR_MALFORMED_DIAGNOSTIC_ATTRIBUTES; -use rustc_span::{Span, Symbol, kw, sym}; +use rustc_span::{Ident, Span, Symbol, kw, sym}; use tracing::{debug, info}; use {rustc_attr_parsing as attr, rustc_hir as hir}; @@ -375,7 +375,7 @@ impl IgnoredDiagnosticOption { #[help] pub struct UnknownFormatParameterForOnUnimplementedAttr { argument_name: Symbol, - trait_name: Symbol, + trait_name: Ident, } #[derive(LintDiagnostic)] @@ -792,7 +792,7 @@ impl<'tcx> OnUnimplementedFormatString { tcx.trait_id_of_impl(item_def_id) .expect("expected `on_unimplemented` to correspond to a trait") }; - let trait_name = tcx.item_name(trait_def_id); + let trait_name = tcx.item_ident(trait_def_id); let generics = tcx.generics_of(item_def_id); let s = self.symbol.as_str(); let mut parser = Parser::new(s, None, None, false, ParseMode::Format); @@ -821,7 +821,11 @@ impl<'tcx> OnUnimplementedFormatString { Position::ArgumentNamed(s) => { match Symbol::intern(s) { // `{ThisTraitsName}` is allowed - s if s == trait_name && !self.is_diagnostic_namespace_variant => (), + s if s == trait_name.name + && !self.is_diagnostic_namespace_variant => + { + () + } s if ALLOWED_FORMAT_SYMBOLS.contains(&s) && !self.is_diagnostic_namespace_variant => { From c08624d8d218beb86d89a794ab285144248c7545 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Mon, 27 Jan 2025 01:21:40 +0000 Subject: [PATCH 72/81] Remove redundant to_ident_string calls --- compiler/rustc_builtin_macros/src/deriving/coerce_pointee.rs | 4 ++-- .../src/errors/wrong_number_of_generic_args.rs | 2 +- compiler/rustc_hir_typeck/src/expr.rs | 5 +---- compiler/rustc_hir_typeck/src/lib.rs | 2 +- compiler/rustc_hir_typeck/src/method/suggest.rs | 2 +- compiler/rustc_lint/src/non_local_def.rs | 2 +- compiler/rustc_lint/src/pass_by_value.rs | 2 +- compiler/rustc_mir_transform/src/errors.rs | 4 ++-- compiler/rustc_mir_transform/src/function_item_references.rs | 4 ++-- compiler/rustc_resolve/src/late/diagnostics.rs | 5 ++--- 10 files changed, 14 insertions(+), 18 deletions(-) diff --git a/compiler/rustc_builtin_macros/src/deriving/coerce_pointee.rs b/compiler/rustc_builtin_macros/src/deriving/coerce_pointee.rs index 49706db0e0b3..82417a86dd9e 100644 --- a/compiler/rustc_builtin_macros/src/deriving/coerce_pointee.rs +++ b/compiler/rustc_builtin_macros/src/deriving/coerce_pointee.rs @@ -157,7 +157,7 @@ pub(crate) fn expand_deriving_coerce_pointee( { cx.dcx().emit_err(RequiresMaybeSized { span: pointee_ty_ident.span, - name: pointee_ty_ident.name.to_ident_string(), + name: pointee_ty_ident, }); return; } @@ -471,5 +471,5 @@ struct TooManyPointees { struct RequiresMaybeSized { #[primary_span] span: Span, - name: String, + name: Ident, } diff --git a/compiler/rustc_hir_analysis/src/errors/wrong_number_of_generic_args.rs b/compiler/rustc_hir_analysis/src/errors/wrong_number_of_generic_args.rs index 5ae7944f6d53..674073497294 100644 --- a/compiler/rustc_hir_analysis/src/errors/wrong_number_of_generic_args.rs +++ b/compiler/rustc_hir_analysis/src/errors/wrong_number_of_generic_args.rs @@ -495,7 +495,7 @@ impl<'a, 'tcx> WrongNumberOfGenericArgs<'a, 'tcx> { .iter() .any(|constraint| constraint.ident.name == item.name) }) - .map(|item| item.name.to_ident_string()) + .map(|item| self.tcx.item_ident(item.def_id).to_string()) .collect() } else { Vec::default() diff --git a/compiler/rustc_hir_typeck/src/expr.rs b/compiler/rustc_hir_typeck/src/expr.rs index bdd436302f48..1c828591bcbd 100644 --- a/compiler/rustc_hir_typeck/src/expr.rs +++ b/compiler/rustc_hir_typeck/src/expr.rs @@ -3337,10 +3337,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { }) .map(|mut field_path| { field_path.pop(); - field_path - .iter() - .map(|id| format!("{}.", id.name.to_ident_string())) - .collect::() + field_path.iter().map(|id| format!("{}.", id)).collect::() }) .collect::>(); candidate_fields.sort(); diff --git a/compiler/rustc_hir_typeck/src/lib.rs b/compiler/rustc_hir_typeck/src/lib.rs index c9e55695e5d9..07e013e4afa6 100644 --- a/compiler/rustc_hir_typeck/src/lib.rs +++ b/compiler/rustc_hir_typeck/src/lib.rs @@ -453,7 +453,7 @@ fn report_unexpected_variant_res( ); let fields = fields .iter() - .map(|field| format!("{}: _", field.name.to_ident_string())) + .map(|field| format!("{}: _", field.ident(tcx))) .collect::>() .join(", "); let sugg = format!(" {{ {} }}", fields); diff --git a/compiler/rustc_hir_typeck/src/method/suggest.rs b/compiler/rustc_hir_typeck/src/method/suggest.rs index 89843da9d7bc..5d4e67d1a0e6 100644 --- a/compiler/rustc_hir_typeck/src/method/suggest.rs +++ b/compiler/rustc_hir_typeck/src/method/suggest.rs @@ -2714,7 +2714,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { .map(|field_path| { field_path .iter() - .map(|id| id.name.to_ident_string()) + .map(|id| id.to_string()) .collect::>() .join(".") }) diff --git a/compiler/rustc_lint/src/non_local_def.rs b/compiler/rustc_lint/src/non_local_def.rs index 1bf19047ade4..4e9d793be5b9 100644 --- a/compiler/rustc_lint/src/non_local_def.rs +++ b/compiler/rustc_lint/src/non_local_def.rs @@ -343,5 +343,5 @@ fn path_span_without_args(path: &Path<'_>) -> Span { /// Return a "error message-able" ident for the last segment of the `Path` fn path_name_to_string(path: &Path<'_>) -> String { - path.segments.last().unwrap().ident.name.to_ident_string() + path.segments.last().unwrap().ident.to_string() } diff --git a/compiler/rustc_lint/src/pass_by_value.rs b/compiler/rustc_lint/src/pass_by_value.rs index 244cd358e9ce..a1d660470589 100644 --- a/compiler/rustc_lint/src/pass_by_value.rs +++ b/compiler/rustc_lint/src/pass_by_value.rs @@ -45,7 +45,7 @@ fn path_for_pass_by_value(cx: &LateContext<'_>, ty: &hir::Ty<'_>) -> Option { - let name = cx.tcx.item_name(def_id).to_ident_string(); + let name = cx.tcx.item_ident(def_id); let path_segment = path.segments.last().unwrap(); return Some(format!("{}{}", name, gen_args(cx, path_segment))); } diff --git a/compiler/rustc_mir_transform/src/errors.rs b/compiler/rustc_mir_transform/src/errors.rs index a2fd46043ca0..29698b0c2e44 100644 --- a/compiler/rustc_mir_transform/src/errors.rs +++ b/compiler/rustc_mir_transform/src/errors.rs @@ -5,7 +5,7 @@ use rustc_middle::mir::AssertKind; use rustc_middle::ty::TyCtxt; use rustc_session::lint::{self, Lint}; use rustc_span::def_id::DefId; -use rustc_span::{Span, Symbol}; +use rustc_span::{Ident, Span, Symbol}; use crate::fluent_generated as fluent; @@ -114,7 +114,7 @@ pub(crate) struct FnItemRef { #[suggestion(code = "{sugg}", applicability = "unspecified")] pub span: Span, pub sugg: String, - pub ident: String, + pub ident: Ident, } #[derive(Diagnostic)] diff --git a/compiler/rustc_mir_transform/src/function_item_references.rs b/compiler/rustc_mir_transform/src/function_item_references.rs index fb21bf9977f1..7e88925b2e1b 100644 --- a/compiler/rustc_mir_transform/src/function_item_references.rs +++ b/compiler/rustc_mir_transform/src/function_item_references.rs @@ -168,7 +168,7 @@ impl<'tcx> FunctionItemRefChecker<'_, 'tcx> { s } }; - let ident = self.tcx.item_name(fn_id).to_ident_string(); + let ident = self.tcx.item_ident(fn_id); let ty_params = fn_args.types().map(|ty| format!("{ty}")); let const_params = fn_args.consts().map(|c| format!("{c}")); let params = ty_params.chain(const_params).join(", "); @@ -177,7 +177,7 @@ impl<'tcx> FunctionItemRefChecker<'_, 'tcx> { let ret = if fn_sig.output().skip_binder().is_unit() { "" } else { " -> _" }; let sugg = format!( "{} as {}{}fn({}{}){}", - if params.is_empty() { ident.clone() } else { format!("{ident}::<{params}>") }, + if params.is_empty() { ident.to_string() } else { format!("{ident}::<{params}>") }, unsafety, abi, vec!["_"; num_args].join(", "), diff --git a/compiler/rustc_resolve/src/late/diagnostics.rs b/compiler/rustc_resolve/src/late/diagnostics.rs index 17c92c7b501c..2db8087fd832 100644 --- a/compiler/rustc_resolve/src/late/diagnostics.rs +++ b/compiler/rustc_resolve/src/late/diagnostics.rs @@ -1636,13 +1636,12 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> { .enumerate() .map(|(idx, new)| (new, old_fields.get(idx))) .map(|(new, old)| { - let new = new.name.to_ident_string(); if let Some(Some(old)) = old - && new != *old + && new.as_str() != old { format!("{new}: {old}") } else { - new + new.to_string() } }) .collect::>() From 0b18b4fbbc5c0a60a1d373b5a1b30d21f55923d1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Le=C3=B3n=20Orell=20Valerian=20Liehr?= Date: Mon, 27 Jan 2025 02:28:04 +0100 Subject: [PATCH 73/81] Remove all dead files inside tests/ui/ --- src/tools/tidy/src/ui_tests.rs | 2 +- .../equality.current.stderr | 17 - .../return-type-notation/equality.next.stderr | 17 - .../issue-110963-late.next.stderr | 11 - .../super-method-bound.next.stderr | 10 - tests/ui/cfg/disallowed-cli-cfgs.test_.stderr | 8 - ...ect-region-supply-region-2.polonius.stderr | 37 - .../trustzone-only.stderr | 9 - .../const-eval/ub-nonnull.chalk.64bit.stderr | 9 - .../const-eval/ub-wide-ptr.chalk.64bit.stderr | 9 - .../consts/write_to_mut_ref_dest.stock.stderr | 23 - ...routine-region-requirements.migrate.stderr | 12 - .../gat-in-trait-path.base.stderr | 52 - .../issue-67510-pass.base.stderr | 19 - .../issue-76535.base.stderr | 57 - .../issue-76535.extended.stderr | 19 - .../issue-78671.base.stderr | 36 - .../issue-78671.extended.stderr | 19 - .../issue-79422.base.stderr | 53 - .../issue-79422.extended.stderr | 36 - .../issue-90014-tait2.next-solver.stderr | 15 - .../issue-91139.migrate.stderr | 7 - .../issue-92096.migrate.stderr | 24 - .../trait-objects.base.stderr | 51 - .../trait-objects.extended.stderr | 19 - .../evaluatable-bounds.unconstrained.stderr | 13 - .../hrtb-perfect-forwarding.polonius.stderr | 71 -- .../auto-trait-coherence.next.stderr | 12 - .../auto-trait-coherence.old.stderr | 12 - ...coherence-treats-tait-ambig.current.stderr | 13 - .../error-handling.polonius.stderr | 15 - .../infinite-instantiation.polonius.stderr | 15 - tests/ui/issues/issue-22638.polonius.stderr | 15 - .../issue-37311.polonius.stderr | 15 - tests/ui/issues/issue-48728.current.stderr | 15 - tests/ui/issues/issue-67552.polonius.stderr | 17 - tests/ui/issues/issue-8727.polonius.stderr | 26 - tests/ui/json/json-multiple.polonius.stderr | 1 - tests/ui/json/json-options.polonius.stderr | 1 - .../inherent-impls-overflow.classic.stderr | 43 - tests/ui/nll/get_default.polonius.stderr | 18 - ...outlives-suggestion-simple.polonius.stderr | 124 -- .../closure-substs.polonius.stderr | 61 - .../empty-types.min_exh_pats.stderr | 727 ----------- ...ately-empty.min_exhaustive_patterns.stderr | 21 - ...ce_of_empty.min_exhaustive_patterns.stderr | 30 - ...n-regular-dropck-recursion.polonius.stderr | 15 - tests/ui/recursion/recursion.polonius.stderr | 15 - .../unreachable.exh_pats.stderr | 55 - .../unreachable.normal.stderr | 44 - .../issue-103052-2.current.stderr | 15 - .../issue-103052-2.next.stderr | 15 - .../disallowed-positions.nofeature.stderr | 1111 ----------------- ...mit-artifact-notifications.polonius.stderr | 1 - .../safe-outside-extern.gated.stderr | 38 - .../safe-outside-extern.ungated.stderr | 89 -- .../safe-impl-trait.ungated.stderr | 8 - .../safe-trait.gated.stderr | 8 - .../safe-trait.ungated.stderr | 8 - ...ault-items-drop-coherence.coherence.stderr | 12 - ...lization-overlap-projection.current.stderr | 30 - ...cialization-overlap-projection.next.stderr | 30 - .../coherence/issue-102048.next.stderr | 16 - .../type-checking-test-3.polonius.stderr | 18 - .../type-checking-test-4.polonius.stderr | 52 - .../panic-causes-oom-112708.stderr | 32 - .../wf-nested.fail.stderr | 17 - .../wf-nested.pass.stderr | 31 - .../wf-nested.pass_sound.stderr | 46 - .../type/pattern_types/derives.noimpl.stderr | 14 - tests/ui/type_length_limit.polonius.stderr | 11 - ...irrefutable.min_exhaustive_patterns.stderr | 26 - 72 files changed, 1 insertion(+), 3592 deletions(-) delete mode 100644 tests/ui/associated-type-bounds/return-type-notation/equality.current.stderr delete mode 100644 tests/ui/associated-type-bounds/return-type-notation/equality.next.stderr delete mode 100644 tests/ui/async-await/return-type-notation/issue-110963-late.next.stderr delete mode 100644 tests/ui/async-await/return-type-notation/super-method-bound.next.stderr delete mode 100644 tests/ui/cfg/disallowed-cli-cfgs.test_.stderr delete mode 100644 tests/ui/closures/closure-expected-type/expect-region-supply-region-2.polonius.stderr delete mode 100644 tests/ui/cmse-nonsecure/cmse-nonsecure-entry/trustzone-only.stderr delete mode 100644 tests/ui/consts/const-eval/ub-nonnull.chalk.64bit.stderr delete mode 100644 tests/ui/consts/const-eval/ub-wide-ptr.chalk.64bit.stderr delete mode 100644 tests/ui/consts/write_to_mut_ref_dest.stock.stderr delete mode 100644 tests/ui/coroutine/coroutine-region-requirements.migrate.stderr delete mode 100644 tests/ui/generic-associated-types/gat-in-trait-path.base.stderr delete mode 100644 tests/ui/generic-associated-types/issue-67510-pass.base.stderr delete mode 100644 tests/ui/generic-associated-types/issue-76535.base.stderr delete mode 100644 tests/ui/generic-associated-types/issue-76535.extended.stderr delete mode 100644 tests/ui/generic-associated-types/issue-78671.base.stderr delete mode 100644 tests/ui/generic-associated-types/issue-78671.extended.stderr delete mode 100644 tests/ui/generic-associated-types/issue-79422.base.stderr delete mode 100644 tests/ui/generic-associated-types/issue-79422.extended.stderr delete mode 100644 tests/ui/generic-associated-types/issue-90014-tait2.next-solver.stderr delete mode 100644 tests/ui/generic-associated-types/issue-91139.migrate.stderr delete mode 100644 tests/ui/generic-associated-types/issue-92096.migrate.stderr delete mode 100644 tests/ui/generic-associated-types/trait-objects.base.stderr delete mode 100644 tests/ui/generic-associated-types/trait-objects.extended.stderr delete mode 100644 tests/ui/generic-const-items/evaluatable-bounds.unconstrained.stderr delete mode 100644 tests/ui/higher-ranked/trait-bounds/hrtb-perfect-forwarding.polonius.stderr delete mode 100644 tests/ui/impl-trait/auto-trait-coherence.next.stderr delete mode 100644 tests/ui/impl-trait/auto-trait-coherence.old.stderr delete mode 100644 tests/ui/impl-trait/coherence-treats-tait-ambig.current.stderr delete mode 100644 tests/ui/impl-trait/multiple-lifetimes/error-handling.polonius.stderr delete mode 100644 tests/ui/infinite/infinite-instantiation.polonius.stderr delete mode 100644 tests/ui/issues/issue-22638.polonius.stderr delete mode 100644 tests/ui/issues/issue-37311-type-length-limit/issue-37311.polonius.stderr delete mode 100644 tests/ui/issues/issue-48728.current.stderr delete mode 100644 tests/ui/issues/issue-67552.polonius.stderr delete mode 100644 tests/ui/issues/issue-8727.polonius.stderr delete mode 100644 tests/ui/json/json-multiple.polonius.stderr delete mode 100644 tests/ui/json/json-options.polonius.stderr delete mode 100644 tests/ui/lazy-type-alias/inherent-impls-overflow.classic.stderr delete mode 100644 tests/ui/nll/get_default.polonius.stderr delete mode 100644 tests/ui/nll/outlives-suggestion-simple.polonius.stderr delete mode 100644 tests/ui/nll/user-annotations/closure-substs.polonius.stderr delete mode 100644 tests/ui/pattern/usefulness/empty-types.min_exh_pats.stderr delete mode 100644 tests/ui/pattern/usefulness/match-privately-empty.min_exhaustive_patterns.stderr delete mode 100644 tests/ui/pattern/usefulness/slice_of_empty.min_exhaustive_patterns.stderr delete mode 100644 tests/ui/recursion/issue-38591-non-regular-dropck-recursion.polonius.stderr delete mode 100644 tests/ui/recursion/recursion.polonius.stderr delete mode 100644 tests/ui/rfcs/rfc-0000-never_patterns/unreachable.exh_pats.stderr delete mode 100644 tests/ui/rfcs/rfc-0000-never_patterns/unreachable.normal.stderr delete mode 100644 tests/ui/rfcs/rfc-1937-termination-trait/issue-103052-2.current.stderr delete mode 100644 tests/ui/rfcs/rfc-1937-termination-trait/issue-103052-2.next.stderr delete mode 100644 tests/ui/rfcs/rfc-2497-if-let-chains/disallowed-positions.nofeature.stderr delete mode 100644 tests/ui/rmeta/emit-artifact-notifications.polonius.stderr delete mode 100644 tests/ui/rust-2024/safe-outside-extern.gated.stderr delete mode 100644 tests/ui/rust-2024/safe-outside-extern.ungated.stderr delete mode 100644 tests/ui/rust-2024/unsafe-extern-blocks/safe-impl-trait.ungated.stderr delete mode 100644 tests/ui/rust-2024/unsafe-extern-blocks/safe-trait.gated.stderr delete mode 100644 tests/ui/rust-2024/unsafe-extern-blocks/safe-trait.ungated.stderr delete mode 100644 tests/ui/specialization/specialization-default-items-drop-coherence.coherence.stderr delete mode 100644 tests/ui/specialization/specialization-overlap-projection.current.stderr delete mode 100644 tests/ui/specialization/specialization-overlap-projection.next.stderr delete mode 100644 tests/ui/traits/next-solver/coherence/issue-102048.next.stderr delete mode 100644 tests/ui/traits/trait-upcasting/type-checking-test-3.polonius.stderr delete mode 100644 tests/ui/traits/trait-upcasting/type-checking-test-4.polonius.stderr delete mode 100644 tests/ui/treat-err-as-bug/panic-causes-oom-112708.stderr delete mode 100644 tests/ui/type-alias-impl-trait/wf-nested.fail.stderr delete mode 100644 tests/ui/type-alias-impl-trait/wf-nested.pass.stderr delete mode 100644 tests/ui/type-alias-impl-trait/wf-nested.pass_sound.stderr delete mode 100644 tests/ui/type/pattern_types/derives.noimpl.stderr delete mode 100644 tests/ui/type_length_limit.polonius.stderr delete mode 100644 tests/ui/uninhabited/uninhabited-irrefutable.min_exhaustive_patterns.stderr diff --git a/src/tools/tidy/src/ui_tests.rs b/src/tools/tidy/src/ui_tests.rs index 5ef07911429b..d66ba157d106 100644 --- a/src/tools/tidy/src/ui_tests.rs +++ b/src/tools/tidy/src/ui_tests.rs @@ -17,7 +17,7 @@ use ignore::Walk; const ENTRY_LIMIT: u32 = 901; // FIXME: The following limits should be reduced eventually. -const ISSUES_ENTRY_LIMIT: u32 = 1662; +const ISSUES_ENTRY_LIMIT: u32 = 1658; const EXPECTED_TEST_FILE_EXTENSIONS: &[&str] = &[ "rs", // test source files diff --git a/tests/ui/associated-type-bounds/return-type-notation/equality.current.stderr b/tests/ui/associated-type-bounds/return-type-notation/equality.current.stderr deleted file mode 100644 index 26b4d935ac7c..000000000000 --- a/tests/ui/associated-type-bounds/return-type-notation/equality.current.stderr +++ /dev/null @@ -1,17 +0,0 @@ -warning: the feature `return_type_notation` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/equality.rs:5:12 - | -LL | #![feature(return_type_notation)] - | ^^^^^^^^^^^^^^^^^^^^ - | - = note: see issue #109417 for more information - = note: `#[warn(incomplete_features)]` on by default - -error: return type notation is not allowed to use type equality - --> $DIR/equality.rs:14:18 - | -LL | fn test>>>() {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -error: aborting due to 1 previous error; 1 warning emitted - diff --git a/tests/ui/associated-type-bounds/return-type-notation/equality.next.stderr b/tests/ui/associated-type-bounds/return-type-notation/equality.next.stderr deleted file mode 100644 index 26b4d935ac7c..000000000000 --- a/tests/ui/associated-type-bounds/return-type-notation/equality.next.stderr +++ /dev/null @@ -1,17 +0,0 @@ -warning: the feature `return_type_notation` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/equality.rs:5:12 - | -LL | #![feature(return_type_notation)] - | ^^^^^^^^^^^^^^^^^^^^ - | - = note: see issue #109417 for more information - = note: `#[warn(incomplete_features)]` on by default - -error: return type notation is not allowed to use type equality - --> $DIR/equality.rs:14:18 - | -LL | fn test>>>() {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -error: aborting due to 1 previous error; 1 warning emitted - diff --git a/tests/ui/async-await/return-type-notation/issue-110963-late.next.stderr b/tests/ui/async-await/return-type-notation/issue-110963-late.next.stderr deleted file mode 100644 index 018f4f2207ae..000000000000 --- a/tests/ui/async-await/return-type-notation/issue-110963-late.next.stderr +++ /dev/null @@ -1,11 +0,0 @@ -warning: the feature `return_type_notation` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/issue-110963-late.rs:6:12 - | -LL | #![feature(return_type_notation)] - | ^^^^^^^^^^^^^^^^^^^^ - | - = note: see issue #109417 for more information - = note: `#[warn(incomplete_features)]` on by default - -warning: 1 warning emitted - diff --git a/tests/ui/async-await/return-type-notation/super-method-bound.next.stderr b/tests/ui/async-await/return-type-notation/super-method-bound.next.stderr deleted file mode 100644 index 5f482b608786..000000000000 --- a/tests/ui/async-await/return-type-notation/super-method-bound.next.stderr +++ /dev/null @@ -1,10 +0,0 @@ -warning: the feature `return_type_notation` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/super-method-bound.rs:6:31 - | -LL | #![feature(return_type_notation)] | ^^^^^^^^^^^^^^^^^^^^ - | - = note: see issue #109417 for more information - = note: `#[warn(incomplete_features)]` on by default - -warning: 1 warning emitted - diff --git a/tests/ui/cfg/disallowed-cli-cfgs.test_.stderr b/tests/ui/cfg/disallowed-cli-cfgs.test_.stderr deleted file mode 100644 index 96b5beb02106..000000000000 --- a/tests/ui/cfg/disallowed-cli-cfgs.test_.stderr +++ /dev/null @@ -1,8 +0,0 @@ -error: unexpected `--cfg test` flag - | - = note: config `test` is only supposed to be controlled by `--test` - = note: see for more information - = note: `#[deny(unexpected_builtin_cfgs)]` on by default - -error: aborting due to 1 previous error - diff --git a/tests/ui/closures/closure-expected-type/expect-region-supply-region-2.polonius.stderr b/tests/ui/closures/closure-expected-type/expect-region-supply-region-2.polonius.stderr deleted file mode 100644 index 8846ccef34e2..000000000000 --- a/tests/ui/closures/closure-expected-type/expect-region-supply-region-2.polonius.stderr +++ /dev/null @@ -1,37 +0,0 @@ -error: lifetime may not live long enough - --> $DIR/expect-region-supply-region-2.rs:14:30 - | -LL | fn expect_bound_supply_named<'x>() { - | -- lifetime `'x` defined here -... -LL | closure_expecting_bound(|x: &'x u32| { - | ^ - let's call the lifetime of this reference `'1` - | | - | requires that `'1` must outlive `'x` - -error[E0521]: borrowed data escapes outside of closure - --> $DIR/expect-region-supply-region-2.rs:20:9 - | -LL | let mut f: Option<&u32> = None; - | ----- `f` declared here, outside of the closure body -... -LL | closure_expecting_bound(|x: &'x u32| { - | - `x` is a reference that is only valid in the closure body -... -LL | f = Some(x); - | ^^^^^^^^^^^ `x` escapes the closure body here - -error: lifetime may not live long enough - --> $DIR/expect-region-supply-region-2.rs:14:30 - | -LL | fn expect_bound_supply_named<'x>() { - | -- lifetime `'x` defined here -... -LL | closure_expecting_bound(|x: &'x u32| { - | ^ requires that `'x` must outlive `'static` - | - = help: consider replacing `'x` with `'static` - -error: aborting due to 3 previous errors - -For more information about this error, try `rustc --explain E0521`. diff --git a/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/trustzone-only.stderr b/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/trustzone-only.stderr deleted file mode 100644 index 77379f7049d0..000000000000 --- a/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/trustzone-only.stderr +++ /dev/null @@ -1,9 +0,0 @@ -error[E0570]: `"C-cmse-nonsecure-entry"` is not a supported ABI for the current target - --> $DIR/trustzone-only.rs:5:1 - | -LL | pub extern "C-cmse-nonsecure-entry" fn entry_function(input: u32) -> u32 { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0570`. diff --git a/tests/ui/consts/const-eval/ub-nonnull.chalk.64bit.stderr b/tests/ui/consts/const-eval/ub-nonnull.chalk.64bit.stderr deleted file mode 100644 index fef6c92af985..000000000000 --- a/tests/ui/consts/const-eval/ub-nonnull.chalk.64bit.stderr +++ /dev/null @@ -1,9 +0,0 @@ -error[E0284]: type annotations needed: cannot satisfy `>::Output == _` - --> $DIR/ub-nonnull.rs:19:30 - | -LL | let out_of_bounds_ptr = &ptr[255]; - | ^^^^^^^^ cannot satisfy `>::Output == _` - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0284`. diff --git a/tests/ui/consts/const-eval/ub-wide-ptr.chalk.64bit.stderr b/tests/ui/consts/const-eval/ub-wide-ptr.chalk.64bit.stderr deleted file mode 100644 index 533db90ce6c9..000000000000 --- a/tests/ui/consts/const-eval/ub-wide-ptr.chalk.64bit.stderr +++ /dev/null @@ -1,9 +0,0 @@ -error[E0282]: type annotations needed - --> $DIR/ub-wide-ptr.rs:90:67 - | -LL | const MYSLICE_SUFFIX_BAD: &MySliceBool = &MySlice(true, [unsafe { mem::transmute(3u8) }]); - | ^^^^^^^^^^^^^^ cannot infer type for type parameter `U` declared on the function `transmute` - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0282`. diff --git a/tests/ui/consts/write_to_mut_ref_dest.stock.stderr b/tests/ui/consts/write_to_mut_ref_dest.stock.stderr deleted file mode 100644 index 688d48ec707c..000000000000 --- a/tests/ui/consts/write_to_mut_ref_dest.stock.stderr +++ /dev/null @@ -1,23 +0,0 @@ -error[E0658]: mutable references are not allowed in constants - --> $DIR/write_to_mut_ref_dest.rs:11:27 - | -LL | let b: *mut u32 = &mut a; - | ^^^^^^ - | - = note: see issue #57349 for more information - = help: add `#![feature(const_mut_refs)]` 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]: dereferencing raw mutable pointers in constants is unstable - --> $DIR/write_to_mut_ref_dest.rs:12:18 - | -LL | unsafe { *b = 5; } - | ^^^^^^ - | - = note: see issue #57349 for more information - = help: add `#![feature(const_mut_refs)]` 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/coroutine/coroutine-region-requirements.migrate.stderr b/tests/ui/coroutine/coroutine-region-requirements.migrate.stderr deleted file mode 100644 index cfee8fc44fe0..000000000000 --- a/tests/ui/coroutine/coroutine-region-requirements.migrate.stderr +++ /dev/null @@ -1,12 +0,0 @@ -error[E0621]: explicit lifetime required in the type of `x` - --> $DIR/generator-region-requirements.rs:16:51 - | -LL | fn dangle(x: &mut i32) -> &'static mut i32 { - | -------- help: add explicit lifetime `'static` to the type of `x`: `&'static mut i32` -... -LL | GeneratorState::Complete(c) => return c, - | ^ lifetime `'static` required - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0621`. diff --git a/tests/ui/generic-associated-types/gat-in-trait-path.base.stderr b/tests/ui/generic-associated-types/gat-in-trait-path.base.stderr deleted file mode 100644 index b2b569e6261b..000000000000 --- a/tests/ui/generic-associated-types/gat-in-trait-path.base.stderr +++ /dev/null @@ -1,52 +0,0 @@ -error[E0038]: the trait `Foo` is not dyn compatible - --> $DIR/gat-in-trait-path.rs:26:17 - | -LL | fn f(_arg : Box Foo = &'a ()>>) {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `Foo` is not dyn compatible - | -note: for a trait to be dyn compatible it needs to allow building a vtable - for more information, visit - --> $DIR/gat-in-trait-path.rs:10:10 - | -LL | trait Foo { - | --- this trait is not dyn compatible... -LL | type A<'a> where Self: 'a; - | ^ ...because it contains the generic associated type `A` - = help: consider moving `A` to another trait - -error[E0038]: the trait `Foo` is not dyn compatible - --> $DIR/gat-in-trait-path.rs:32:5 - | -LL | f(Box::new(foo)); - | ^^^^^^^^^^^^^ `Foo` is not dyn compatible - | -note: for a trait to be dyn compatible it needs to allow building a vtable - for more information, visit - --> $DIR/gat-in-trait-path.rs:10:10 - | -LL | trait Foo { - | --- this trait is not dyn compatible... -LL | type A<'a> where Self: 'a; - | ^ ...because it contains the generic associated type `A` - = help: consider moving `A` to another trait - -error[E0038]: the trait `Foo` is not dyn compatible - --> $DIR/gat-in-trait-path.rs:32:5 - | -LL | f(Box::new(foo)); - | ^^^^^^^^^^^^^ `Foo` is not dyn compatible - | -note: for a trait to be dyn compatible it needs to allow building a vtable - for more information, visit - --> $DIR/gat-in-trait-path.rs:10:10 - | -LL | trait Foo { - | --- this trait is not dyn compatible... -LL | type A<'a> where Self: 'a; - | ^ ...because it contains the generic associated type `A` - = help: consider moving `A` to another trait - = note: required for the cast from `Box>` to `Box<(dyn Foo = &'a ()> + 'static)>` - -error: aborting due to 3 previous errors - -For more information about this error, try `rustc --explain E0038`. diff --git a/tests/ui/generic-associated-types/issue-67510-pass.base.stderr b/tests/ui/generic-associated-types/issue-67510-pass.base.stderr deleted file mode 100644 index 563089489694..000000000000 --- a/tests/ui/generic-associated-types/issue-67510-pass.base.stderr +++ /dev/null @@ -1,19 +0,0 @@ -error[E0038]: the trait `X` is not dyn compatible - --> $DIR/issue-67510-pass.rs:12:23 - | -LL | fn _func1<'a>(_x: Box=&'a ()>>) {} - | ^^^^^^^^^^^^^^^^^^^ `X` is not dyn compatible - | -note: for a trait to be dyn compatible it needs to allow building a vtable - for more information, visit - --> $DIR/issue-67510-pass.rs:9:10 - | -LL | trait X { - | - this trait is not dyn compatible... -LL | type Y<'a>; - | ^ ...because it contains the generic associated type `Y` - = help: consider moving `Y` to another trait - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0038`. diff --git a/tests/ui/generic-associated-types/issue-76535.base.stderr b/tests/ui/generic-associated-types/issue-76535.base.stderr deleted file mode 100644 index b503fad2d84f..000000000000 --- a/tests/ui/generic-associated-types/issue-76535.base.stderr +++ /dev/null @@ -1,57 +0,0 @@ -error[E0107]: missing generics for associated type `SuperTrait::SubType` - --> $DIR/issue-76535.rs:39:33 - | -LL | let sub: Box> = Box::new(SuperStruct::new(0)); - | ^^^^^^^ expected 1 lifetime argument - | -note: associated type defined here, with 1 lifetime parameter: `'a` - --> $DIR/issue-76535.rs:9:10 - | -LL | type SubType<'a>: SubTrait where Self: 'a; - | ^^^^^^^ -- -help: add missing lifetime argument - | -LL | let sub: Box = SubStruct>> = Box::new(SuperStruct::new(0)); - | ++++ - -error[E0038]: the trait `SuperTrait` is not dyn compatible - --> $DIR/issue-76535.rs:39:14 - | -LL | let sub: Box> = Box::new(SuperStruct::new(0)); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `SuperTrait` is not dyn compatible - | -note: for a trait to be dyn compatible it needs to allow building a vtable - for more information, visit - --> $DIR/issue-76535.rs:9:10 - | -LL | pub trait SuperTrait { - | ---------- this trait is not dyn compatible... -LL | type SubType<'a>: SubTrait where Self: 'a; - | ^^^^^^^ ...because it contains the generic associated type `SubType` - = help: consider moving `SubType` to another trait - = help: only type `SuperStruct` implements `SuperTrait` within this crate. Consider using it directly instead. - = note: `SuperTrait` may be implemented in other crates; if you want to support your users passing their own types here, you can't refer to a specific type - -error[E0038]: the trait `SuperTrait` is not dyn compatible - --> $DIR/issue-76535.rs:39:57 - | -LL | let sub: Box> = Box::new(SuperStruct::new(0)); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `SuperTrait` is not dyn compatible - | -note: for a trait to be dyn compatible it needs to allow building a vtable - for more information, visit - --> $DIR/issue-76535.rs:9:10 - | -LL | pub trait SuperTrait { - | ---------- this trait is not dyn compatible... -LL | type SubType<'a>: SubTrait where Self: 'a; - | ^^^^^^^ ...because it contains the generic associated type `SubType` - = help: consider moving `SubType` to another trait - = help: only type `SuperStruct` implements `SuperTrait` within this crate. Consider using it directly instead. - = note: `SuperTrait` may be implemented in other crates; if you want to support your users passing their own types here, you can't refer to a specific type - = note: required for the cast from `Box` to `Box = SubStruct<'_>>>` - -error: aborting due to 3 previous errors - -Some errors have detailed explanations: E0038, E0107. -For more information about an error, try `rustc --explain E0038`. diff --git a/tests/ui/generic-associated-types/issue-76535.extended.stderr b/tests/ui/generic-associated-types/issue-76535.extended.stderr deleted file mode 100644 index f6fe8b16902b..000000000000 --- a/tests/ui/generic-associated-types/issue-76535.extended.stderr +++ /dev/null @@ -1,19 +0,0 @@ -error[E0107]: missing generics for associated type `SuperTrait::SubType` - --> $DIR/issue-76535.rs:39:33 - | -LL | let sub: Box> = Box::new(SuperStruct::new(0)); - | ^^^^^^^ expected 1 lifetime argument - | -note: associated type defined here, with 1 lifetime parameter: `'a` - --> $DIR/issue-76535.rs:9:10 - | -LL | type SubType<'a>: SubTrait where Self: 'a; - | ^^^^^^^ -- -help: add missing lifetime argument - | -LL | let sub: Box = SubStruct>> = Box::new(SuperStruct::new(0)); - | ++++ - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0107`. diff --git a/tests/ui/generic-associated-types/issue-78671.base.stderr b/tests/ui/generic-associated-types/issue-78671.base.stderr deleted file mode 100644 index 9bfe8c0b9561..000000000000 --- a/tests/ui/generic-associated-types/issue-78671.base.stderr +++ /dev/null @@ -1,36 +0,0 @@ -error[E0107]: missing generics for associated type `CollectionFamily::Member` - --> $DIR/issue-78671.rs:10:47 - | -LL | Box::new(Family) as &dyn CollectionFamily - | ^^^^^^ expected 1 generic argument - | -note: associated type defined here, with 1 generic parameter: `T` - --> $DIR/issue-78671.rs:7:10 - | -LL | type Member; - | ^^^^^^ - -help: add missing generic argument - | -LL | Box::new(Family) as &dyn CollectionFamily=usize> - | +++ - -error[E0038]: the trait `CollectionFamily` is not dyn compatible - --> $DIR/issue-78671.rs:10:25 - | -LL | Box::new(Family) as &dyn CollectionFamily - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `CollectionFamily` is not dyn compatible - | -note: for a trait to be dyn compatible it needs to allow building a vtable - for more information, visit - --> $DIR/issue-78671.rs:7:10 - | -LL | trait CollectionFamily { - | ---------------- this trait is not dyn compatible... -LL | type Member; - | ^^^^^^ ...because it contains the generic associated type `Member` - = help: consider moving `Member` to another trait - -error: aborting due to 2 previous errors - -Some errors have detailed explanations: E0038, E0107. -For more information about an error, try `rustc --explain E0038`. diff --git a/tests/ui/generic-associated-types/issue-78671.extended.stderr b/tests/ui/generic-associated-types/issue-78671.extended.stderr deleted file mode 100644 index a5d56256d283..000000000000 --- a/tests/ui/generic-associated-types/issue-78671.extended.stderr +++ /dev/null @@ -1,19 +0,0 @@ -error[E0107]: missing generics for associated type `CollectionFamily::Member` - --> $DIR/issue-78671.rs:10:47 - | -LL | Box::new(Family) as &dyn CollectionFamily - | ^^^^^^ expected 1 generic argument - | -note: associated type defined here, with 1 generic parameter: `T` - --> $DIR/issue-78671.rs:7:10 - | -LL | type Member; - | ^^^^^^ - -help: add missing generic argument - | -LL | Box::new(Family) as &dyn CollectionFamily=usize> - | +++ - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0107`. diff --git a/tests/ui/generic-associated-types/issue-79422.base.stderr b/tests/ui/generic-associated-types/issue-79422.base.stderr deleted file mode 100644 index c3de2b71762e..000000000000 --- a/tests/ui/generic-associated-types/issue-79422.base.stderr +++ /dev/null @@ -1,53 +0,0 @@ -error[E0107]: missing generics for associated type `MapLike::VRefCont` - --> $DIR/issue-79422.rs:47:36 - | -LL | as Box>>; - | ^^^^^^^^ expected 1 lifetime argument - | -note: associated type defined here, with 1 lifetime parameter: `'a` - --> $DIR/issue-79422.rs:23:10 - | -LL | type VRefCont<'a>: RefCont<'a, V> where Self: 'a; - | ^^^^^^^^ -- -help: add missing lifetime argument - | -LL | as Box = dyn RefCont<'_, u8>>>; - | ++++ - -error[E0038]: the trait `MapLike` is not dyn compatible - --> $DIR/issue-79422.rs:47:12 - | -LL | as Box>>; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `MapLike` is not dyn compatible - | -note: for a trait to be dyn compatible it needs to allow building a vtable - for more information, visit - --> $DIR/issue-79422.rs:23:10 - | -LL | trait MapLike { - | ------- this trait is not dyn compatible... -LL | type VRefCont<'a>: RefCont<'a, V> where Self: 'a; - | ^^^^^^^^ ...because it contains the generic associated type `VRefCont` - = help: consider moving `VRefCont` to another trait - -error[E0038]: the trait `MapLike` is not dyn compatible - --> $DIR/issue-79422.rs:44:13 - | -LL | let m = Box::new(std::collections::BTreeMap::::new()) - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `MapLike` is not dyn compatible - | -note: for a trait to be dyn compatible it needs to allow building a vtable - for more information, visit - --> $DIR/issue-79422.rs:23:10 - | -LL | trait MapLike { - | ------- this trait is not dyn compatible... -LL | type VRefCont<'a>: RefCont<'a, V> where Self: 'a; - | ^^^^^^^^ ...because it contains the generic associated type `VRefCont` - = help: consider moving `VRefCont` to another trait - = note: required for the cast from `Box>` to `Box = (dyn RefCont<'_, u8> + 'static)>>` - -error: aborting due to 3 previous errors - -Some errors have detailed explanations: E0038, E0107. -For more information about an error, try `rustc --explain E0038`. diff --git a/tests/ui/generic-associated-types/issue-79422.extended.stderr b/tests/ui/generic-associated-types/issue-79422.extended.stderr deleted file mode 100644 index 031f8d8d851a..000000000000 --- a/tests/ui/generic-associated-types/issue-79422.extended.stderr +++ /dev/null @@ -1,36 +0,0 @@ -error[E0107]: missing generics for associated type `MapLike::VRefCont` - --> $DIR/issue-79422.rs:47:36 - | -LL | as Box>>; - | ^^^^^^^^ expected 1 lifetime argument - | -note: associated type defined here, with 1 lifetime parameter: `'a` - --> $DIR/issue-79422.rs:23:10 - | -LL | type VRefCont<'a>: RefCont<'a, V> where Self: 'a; - | ^^^^^^^^ -- -help: add missing lifetime argument - | -LL | as Box = dyn RefCont<'_, u8>>>; - | ++++ - -error[E0271]: type mismatch resolving ` as MapLike>::VRefCont<'_> == dyn RefCont<'_, u8>` - --> $DIR/issue-79422.rs:44:13 - | -LL | let m = Box::new(std::collections::BTreeMap::::new()) - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type mismatch resolving ` as MapLike>::VRefCont<'_> == dyn RefCont<'_, u8>` - | -note: expected this to be `(dyn RefCont<'_, u8> + 'static)` - --> $DIR/issue-79422.rs:28:25 - | -LL | type VRefCont<'a> = &'a V where Self: 'a; - | ^^^^^ - = note: expected trait object `(dyn RefCont<'_, u8> + 'static)` - found reference `&u8` - = help: `&u8` implements `RefCont` so you could box the found value and coerce it to the trait object `Box`, you will have to change the expected type as well - = note: required for the cast from `Box>` to `Box = (dyn RefCont<'_, u8> + 'static)>>` - -error: aborting due to 2 previous errors - -Some errors have detailed explanations: E0107, E0271. -For more information about an error, try `rustc --explain E0107`. diff --git a/tests/ui/generic-associated-types/issue-90014-tait2.next-solver.stderr b/tests/ui/generic-associated-types/issue-90014-tait2.next-solver.stderr deleted file mode 100644 index 85c5dad7fc01..000000000000 --- a/tests/ui/generic-associated-types/issue-90014-tait2.next-solver.stderr +++ /dev/null @@ -1,15 +0,0 @@ -error[E0308]: mismatched types - --> $DIR/issue-90014-tait2.rs:27:9 - | -LL | fn make_fut(&self) -> Box Trait<'a, Thing = Fut<'a>>> { - | ------------------------------------------- expected `Box<(dyn for<'a> Trait<'a, Thing = Fut<'a>> + 'static)>` because of return type -LL | Box::new((async { () },)) - | ^^^^^^^^^^^^^^^^^^^^^^^^^ expected `Box>>`, found `Box<(...,)>` - | - = note: expected struct `Box<(dyn for<'a> Trait<'a, Thing = Fut<'a>> + 'static)>` - found struct `Box<({async block@$DIR/issue-90014-tait2.rs:27:19: 27:31},)>` - = help: `({async block@$DIR/issue-90014-tait2.rs:27:19: 27:31},)` implements `Trait` so you could box the found value and coerce it to the trait object `Box`, you will have to change the expected type as well - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/generic-associated-types/issue-91139.migrate.stderr b/tests/ui/generic-associated-types/issue-91139.migrate.stderr deleted file mode 100644 index e3b658558e32..000000000000 --- a/tests/ui/generic-associated-types/issue-91139.migrate.stderr +++ /dev/null @@ -1,7 +0,0 @@ -error: expected identifier, found `<<` - --> $DIR/issue-91139.rs:1:1 - | - | ^^ expected identifier - -error: aborting due to 1 previous error - diff --git a/tests/ui/generic-associated-types/issue-92096.migrate.stderr b/tests/ui/generic-associated-types/issue-92096.migrate.stderr deleted file mode 100644 index ce1fd6dd9831..000000000000 --- a/tests/ui/generic-associated-types/issue-92096.migrate.stderr +++ /dev/null @@ -1,24 +0,0 @@ -error[E0311]: the parameter type `C` may not live long enough - --> $DIR/issue-92096.rs:19:33 - | -LL | fn call_connect(c: &'_ C) -> impl '_ + Future + Send - | ^^^^^^^^^^^^^^^^^^^^^^^ ...so that the type `C` will meet its required lifetime bounds - | -help: consider adding an explicit lifetime bound... - | -LL | C: Client + Send + Sync + 'a, - | ++++ - -error[E0311]: the parameter type `C` may not live long enough - --> $DIR/issue-92096.rs:19:33 - | -LL | fn call_connect(c: &'_ C) -> impl '_ + Future + Send - | ^^^^^^^^^^^^^^^^^^^^^^^ ...so that the type `C` will meet its required lifetime bounds - | -help: consider adding an explicit lifetime bound... - | -LL | C: Client + Send + Sync + 'a, - | ++++ - -error: aborting due to 2 previous errors - diff --git a/tests/ui/generic-associated-types/trait-objects.base.stderr b/tests/ui/generic-associated-types/trait-objects.base.stderr deleted file mode 100644 index fe9ab165d4af..000000000000 --- a/tests/ui/generic-associated-types/trait-objects.base.stderr +++ /dev/null @@ -1,51 +0,0 @@ -error[E0038]: the trait `StreamingIterator` is not dyn compatible - --> $DIR/trait-objects.rs:13:21 - | -LL | fn min_size(x: &mut dyn for<'a> StreamingIterator = &'a i32>) -> usize { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `StreamingIterator` is not dyn compatible - | -note: for a trait to be dyn compatible it needs to allow building a vtable - for more information, visit - --> $DIR/trait-objects.rs:7:10 - | -LL | trait StreamingIterator { - | ----------------- this trait is not dyn compatible... -LL | type Item<'a> where Self: 'a; - | ^^^^ ...because it contains the generic associated type `Item` - = help: consider moving `Item` to another trait - -error[E0038]: the trait `StreamingIterator` is not dyn compatible - --> $DIR/trait-objects.rs:15:7 - | -LL | x.size_hint().0 - | ^^^^^^^^^ `StreamingIterator` is not dyn compatible - | -note: for a trait to be dyn compatible it needs to allow building a vtable - for more information, visit - --> $DIR/trait-objects.rs:7:10 - | -LL | trait StreamingIterator { - | ----------------- this trait is not dyn compatible... -LL | type Item<'a> where Self: 'a; - | ^^^^ ...because it contains the generic associated type `Item` - = help: consider moving `Item` to another trait - -error[E0038]: the trait `StreamingIterator` is not dyn compatible - --> $DIR/trait-objects.rs:15:5 - | -LL | x.size_hint().0 - | ^^^^^^^^^^^^^ `StreamingIterator` is not dyn compatible - | -note: for a trait to be dyn compatible it needs to allow building a vtable - for more information, visit - --> $DIR/trait-objects.rs:7:10 - | -LL | trait StreamingIterator { - | ----------------- this trait is not dyn compatible... -LL | type Item<'a> where Self: 'a; - | ^^^^ ...because it contains the generic associated type `Item` - = help: consider moving `Item` to another trait - -error: aborting due to 3 previous errors - -For more information about this error, try `rustc --explain E0038`. diff --git a/tests/ui/generic-associated-types/trait-objects.extended.stderr b/tests/ui/generic-associated-types/trait-objects.extended.stderr deleted file mode 100644 index 9f9418e20b9d..000000000000 --- a/tests/ui/generic-associated-types/trait-objects.extended.stderr +++ /dev/null @@ -1,19 +0,0 @@ -error[E0521]: borrowed data escapes outside of function - --> $DIR/trait-objects.rs:15:5 - | -LL | fn min_size(x: &mut dyn for<'a> StreamingIterator = &'a i32>) -> usize { - | - - let's call the lifetime of this reference `'1` - | | - | `x` is a reference that is only valid in the function body -LL | -LL | x.size_hint().0 - | ^^^^^^^^^^^^^ - | | - | `x` escapes the function body here - | argument requires that `'1` must outlive `'static` - | - = note: due to current limitations in the borrow checker, this implies a `'static` lifetime - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0521`. diff --git a/tests/ui/generic-const-items/evaluatable-bounds.unconstrained.stderr b/tests/ui/generic-const-items/evaluatable-bounds.unconstrained.stderr deleted file mode 100644 index b6f9bdce1cb7..000000000000 --- a/tests/ui/generic-const-items/evaluatable-bounds.unconstrained.stderr +++ /dev/null @@ -1,13 +0,0 @@ -error: unconstrained generic constant - --> $DIR/evaluatable-bounds.rs:16:5 - | -LL | const ARRAY: [i32; Self::LEN]; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | -help: try adding a `where` bound - | -LL | const ARRAY: [i32; Self::LEN] where [(); Self::LEN]:; - | ++++++++++++++++++++++ - -error: aborting due to 1 previous error - diff --git a/tests/ui/higher-ranked/trait-bounds/hrtb-perfect-forwarding.polonius.stderr b/tests/ui/higher-ranked/trait-bounds/hrtb-perfect-forwarding.polonius.stderr deleted file mode 100644 index 795484f11088..000000000000 --- a/tests/ui/higher-ranked/trait-bounds/hrtb-perfect-forwarding.polonius.stderr +++ /dev/null @@ -1,71 +0,0 @@ -warning: function cannot return without recursing - --> $DIR/hrtb-perfect-forwarding.rs:16:1 - | -LL | / fn no_hrtb<'b, T>(mut t: T) -LL | | where -LL | | T: Bar<&'b isize>, -LL | | { -... | -LL | | no_hrtb(&mut t); - | | --------------- recursive call site -LL | | } - | |_^ cannot return without recursing - | - = note: `#[warn(unconditional_recursion)]` on by default - = help: a `loop` may express intention better if this is on purpose - -warning: function cannot return without recursing - --> $DIR/hrtb-perfect-forwarding.rs:25:1 - | -LL | / fn bar_hrtb(mut t: T) -LL | | where -LL | | T: for<'b> Bar<&'b isize>, -LL | | { -... | -LL | | bar_hrtb(&mut t); - | | ---------------- recursive call site -LL | | } - | |_^ cannot return without recursing - | - = help: a `loop` may express intention better if this is on purpose - -warning: function cannot return without recursing - --> $DIR/hrtb-perfect-forwarding.rs:35:1 - | -LL | / fn foo_hrtb_bar_not<'b, T>(mut t: T) -LL | | where -LL | | T: for<'a> Foo<&'a isize> + Bar<&'b isize>, -LL | | { -... | -LL | | foo_hrtb_bar_not(&mut t); - | | ------------------------ recursive call site -LL | | -LL | | -LL | | } - | |_^ cannot return without recursing - | - = help: a `loop` may express intention better if this is on purpose - -error: higher-ranked subtype error - --> $DIR/hrtb-perfect-forwarding.rs:43:5 - | -LL | foo_hrtb_bar_not(&mut t); - | ^^^^^^^^^^^^^^^^^^^^^^^^ - -warning: function cannot return without recursing - --> $DIR/hrtb-perfect-forwarding.rs:48:1 - | -LL | / fn foo_hrtb_bar_hrtb(mut t: T) -LL | | where -LL | | T: for<'a> Foo<&'a isize> + for<'b> Bar<&'b isize>, -LL | | { -LL | | // OK -- now we have `T : for<'b> Bar<&'b isize>`. -LL | | foo_hrtb_bar_hrtb(&mut t); - | | ------------------------- recursive call site -LL | | } - | |_^ cannot return without recursing - | - = help: a `loop` may express intention better if this is on purpose - -error: aborting due to 1 previous error; 4 warnings emitted - diff --git a/tests/ui/impl-trait/auto-trait-coherence.next.stderr b/tests/ui/impl-trait/auto-trait-coherence.next.stderr deleted file mode 100644 index cd91bfcb48d7..000000000000 --- a/tests/ui/impl-trait/auto-trait-coherence.next.stderr +++ /dev/null @@ -1,12 +0,0 @@ -error[E0119]: conflicting implementations of trait `AnotherTrait` for type `D<_>` - --> $DIR/auto-trait-coherence.rs:24:1 - | -LL | impl AnotherTrait for T {} - | -------------------------------- first implementation here -... -LL | impl AnotherTrait for D { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `D<_>` - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0119`. diff --git a/tests/ui/impl-trait/auto-trait-coherence.old.stderr b/tests/ui/impl-trait/auto-trait-coherence.old.stderr deleted file mode 100644 index cd91bfcb48d7..000000000000 --- a/tests/ui/impl-trait/auto-trait-coherence.old.stderr +++ /dev/null @@ -1,12 +0,0 @@ -error[E0119]: conflicting implementations of trait `AnotherTrait` for type `D<_>` - --> $DIR/auto-trait-coherence.rs:24:1 - | -LL | impl AnotherTrait for T {} - | -------------------------------- first implementation here -... -LL | impl AnotherTrait for D { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `D<_>` - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0119`. diff --git a/tests/ui/impl-trait/coherence-treats-tait-ambig.current.stderr b/tests/ui/impl-trait/coherence-treats-tait-ambig.current.stderr deleted file mode 100644 index 444f3d6689f2..000000000000 --- a/tests/ui/impl-trait/coherence-treats-tait-ambig.current.stderr +++ /dev/null @@ -1,13 +0,0 @@ -error[E0119]: conflicting implementations of trait `Into` for type `Foo` - --> $DIR/coherence-treats-tait-ambig.rs:10:1 - | -LL | impl Into for Foo { - | ^^^^^^^^^^^^^^^^^^^^ - | - = note: conflicting implementation in crate `core`: - - impl Into for T - where U: From; - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0119`. diff --git a/tests/ui/impl-trait/multiple-lifetimes/error-handling.polonius.stderr b/tests/ui/impl-trait/multiple-lifetimes/error-handling.polonius.stderr deleted file mode 100644 index c511081a86ff..000000000000 --- a/tests/ui/impl-trait/multiple-lifetimes/error-handling.polonius.stderr +++ /dev/null @@ -1,15 +0,0 @@ -error: lifetime may not live long enough - --> $DIR/error-handling.rs:22:16 - | -LL | fn foo<'a, 'b, 'c>(x: &'static i32, mut y: &'a i32) -> E<'b, 'c> { - | -- -- lifetime `'b` defined here - | | - | lifetime `'a` defined here -... -LL | let _: &'b i32 = *u.0; - | ^^^^^^^ type annotation requires that `'a` must outlive `'b` - | - = help: consider adding the following bound: `'a: 'b` - -error: aborting due to 1 previous error - diff --git a/tests/ui/infinite/infinite-instantiation.polonius.stderr b/tests/ui/infinite/infinite-instantiation.polonius.stderr deleted file mode 100644 index f048c942f1a7..000000000000 --- a/tests/ui/infinite/infinite-instantiation.polonius.stderr +++ /dev/null @@ -1,15 +0,0 @@ -error: reached the recursion limit while instantiating `function::>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>` - --> $DIR/infinite-instantiation.rs:22:9 - | -LL | function(counter - 1, t.to_option()); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | -note: `function` defined here - --> $DIR/infinite-instantiation.rs:20:1 - | -LL | fn function(counter: usize, t: T) { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - = note: the full type name has been written to '$TEST_BUILD_DIR/infinite/infinite-instantiation.polonius/infinite-instantiation.long-type.txt' - -error: aborting due to 1 previous error - diff --git a/tests/ui/issues/issue-22638.polonius.stderr b/tests/ui/issues/issue-22638.polonius.stderr deleted file mode 100644 index 3a94ed7bd3da..000000000000 --- a/tests/ui/issues/issue-22638.polonius.stderr +++ /dev/null @@ -1,15 +0,0 @@ -error: reached the recursion limit while instantiating `A::matches::$CLOSURE` - --> $DIR/issue-22638.rs:56:9 - | -LL | a.matches(f) - | ^^^^^^^^^^^^ - | -note: `A::matches` defined here - --> $DIR/issue-22638.rs:15:5 - | -LL | pub fn matches(&self, f: &F) { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - = note: the full type name has been written to '$TEST_BUILD_DIR/issues/issue-22638.polonius/issue-22638.long-type.txt' - -error: aborting due to 1 previous error - diff --git a/tests/ui/issues/issue-37311-type-length-limit/issue-37311.polonius.stderr b/tests/ui/issues/issue-37311-type-length-limit/issue-37311.polonius.stderr deleted file mode 100644 index 08b4573dd0b8..000000000000 --- a/tests/ui/issues/issue-37311-type-length-limit/issue-37311.polonius.stderr +++ /dev/null @@ -1,15 +0,0 @@ -error: reached the recursion limit while instantiating `<(&(&(&(&(&(&(&(&(&(&(&(&(&(&(&(.....), ...), ...) as Foo>::recurse` - --> $DIR/issue-37311.rs:17:9 - | -LL | (self, self).recurse(); - | ^^^^^^^^^^^^^^^^^^^^^^ - | -note: `::recurse` defined here - --> $DIR/issue-37311.rs:16:5 - | -LL | fn recurse(&self) { - | ^^^^^^^^^^^^^^^^^ - = note: the full type name has been written to '$TEST_BUILD_DIR/issues/issue-37311-type-length-limit/issue-37311.polonius/issue-37311.long-type.txt' - -error: aborting due to 1 previous error - diff --git a/tests/ui/issues/issue-48728.current.stderr b/tests/ui/issues/issue-48728.current.stderr deleted file mode 100644 index 2a1b4ff78185..000000000000 --- a/tests/ui/issues/issue-48728.current.stderr +++ /dev/null @@ -1,15 +0,0 @@ -error[E0119]: conflicting implementations of trait `Clone` for type `Node<[_]>` - --> $DIR/issue-48728.rs:9:10 - | -LL | #[derive(Clone)] - | ^^^^^ conflicting implementation for `Node<[_]>` -... -LL | impl Clone for Node<[T]> { - | ------------------------------------------- first implementation here - | - = note: upstream crates may add a new impl of trait `std::clone::Clone` for type `[_]` in future versions - = note: this error originates in the derive macro `Clone` (in Nightly builds, run with -Z macro-backtrace for more info) - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0119`. diff --git a/tests/ui/issues/issue-67552.polonius.stderr b/tests/ui/issues/issue-67552.polonius.stderr deleted file mode 100644 index ca42f87e8194..000000000000 --- a/tests/ui/issues/issue-67552.polonius.stderr +++ /dev/null @@ -1,17 +0,0 @@ -error: reached the recursion limit while instantiating `rec::<&mut &mut &mut &mut &mut &... &mut &mut &mut &mut &mut Empty>` - --> $DIR/issue-67552.rs:28:9 - | -LL | rec(identity(&mut it)) - | ^^^^^^^^^^^^^^^^^^^^^^ - | -note: `rec` defined here - --> $DIR/issue-67552.rs:21:1 - | -LL | / fn rec(mut it: T) -LL | | where -LL | | T: Iterator, - | |________________^ - = note: the full type name has been written to '$TEST_BUILD_DIR/issues/issue-67552.polonius/issue-67552.long-type.txt' - -error: aborting due to 1 previous error - diff --git a/tests/ui/issues/issue-8727.polonius.stderr b/tests/ui/issues/issue-8727.polonius.stderr deleted file mode 100644 index 4fb8c2b3aff1..000000000000 --- a/tests/ui/issues/issue-8727.polonius.stderr +++ /dev/null @@ -1,26 +0,0 @@ -warning: function cannot return without recursing - --> $DIR/issue-8727.rs:7:1 - | -LL | fn generic() { - | ^^^^^^^^^^^^^^^ cannot return without recursing -LL | generic::>(); - | ---------------------- recursive call site - | - = note: `#[warn(unconditional_recursion)]` on by default - = help: a `loop` may express intention better if this is on purpose - -error: reached the recursion limit while instantiating `generic::>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>` - --> $DIR/issue-8727.rs:8:5 - | -LL | generic::>(); - | ^^^^^^^^^^^^^^^^^^^^^^ - | -note: `generic` defined here - --> $DIR/issue-8727.rs:7:1 - | -LL | fn generic() { - | ^^^^^^^^^^^^^^^ - = note: the full type name has been written to '$TEST_BUILD_DIR/issues/issue-8727.polonius/issue-8727.long-type.txt' - -error: aborting due to 1 previous error; 1 warning emitted - diff --git a/tests/ui/json/json-multiple.polonius.stderr b/tests/ui/json/json-multiple.polonius.stderr deleted file mode 100644 index 0e4d442f299c..000000000000 --- a/tests/ui/json/json-multiple.polonius.stderr +++ /dev/null @@ -1 +0,0 @@ -{"artifact":"$TEST_BUILD_DIR/json-multiple.polonius/libjson_multiple.rlib","emit":"link"} diff --git a/tests/ui/json/json-options.polonius.stderr b/tests/ui/json/json-options.polonius.stderr deleted file mode 100644 index e21f6f85d162..000000000000 --- a/tests/ui/json/json-options.polonius.stderr +++ /dev/null @@ -1 +0,0 @@ -{"artifact":"$TEST_BUILD_DIR/json-options.polonius/libjson_options.rlib","emit":"link"} diff --git a/tests/ui/lazy-type-alias/inherent-impls-overflow.classic.stderr b/tests/ui/lazy-type-alias/inherent-impls-overflow.classic.stderr deleted file mode 100644 index 2f00a877142c..000000000000 --- a/tests/ui/lazy-type-alias/inherent-impls-overflow.classic.stderr +++ /dev/null @@ -1,43 +0,0 @@ -error[E0275]: overflow normalizing the type alias `Loop` - --> $DIR/inherent-impls-overflow.rs:7:13 - | -LL | type Loop = Loop; - | ^^^^ - | - = note: in case this is a recursive type alias, consider using a struct, enum, or union instead - -error[E0275]: overflow normalizing the type alias `Loop` - --> $DIR/inherent-impls-overflow.rs:9:1 - | -LL | impl Loop {} - | ^^^^^^^^^^^^ - | - = note: in case this is a recursive type alias, consider using a struct, enum, or union instead - -error[E0275]: overflow normalizing the type alias `Poly0<(((((((...,),),),),),),)>` - --> $DIR/inherent-impls-overflow.rs:13:17 - | -LL | type Poly0 = Poly1<(T,)>; - | ^^^^^^^^^^^ - | - = note: in case this is a recursive type alias, consider using a struct, enum, or union instead - -error[E0275]: overflow normalizing the type alias `Poly1<(((((((...,),),),),),),)>` - --> $DIR/inherent-impls-overflow.rs:16:17 - | -LL | type Poly1 = Poly0<(T,)>; - | ^^^^^^^^^^^ - | - = note: in case this is a recursive type alias, consider using a struct, enum, or union instead - -error[E0275]: overflow normalizing the type alias `Poly1<(((((((...,),),),),),),)>` - --> $DIR/inherent-impls-overflow.rs:20:1 - | -LL | impl Poly0<()> {} - | ^^^^^^^^^^^^^^^^^ - | - = note: in case this is a recursive type alias, consider using a struct, enum, or union instead - -error: aborting due to 5 previous errors - -For more information about this error, try `rustc --explain E0275`. diff --git a/tests/ui/nll/get_default.polonius.stderr b/tests/ui/nll/get_default.polonius.stderr deleted file mode 100644 index 613d06cce915..000000000000 --- a/tests/ui/nll/get_default.polonius.stderr +++ /dev/null @@ -1,18 +0,0 @@ -error[E0502]: cannot borrow `*map` as mutable because it is also borrowed as immutable - --> $DIR/get_default.rs:32:17 - | -LL | fn err(map: &mut Map) -> &String { - | - let's call the lifetime of this reference `'1` -LL | loop { -LL | match map.get() { - | --- immutable borrow occurs here -LL | Some(v) => { -LL | map.set(String::new()); // Both AST and MIR error here - | ^^^ mutable borrow occurs here -LL | -LL | return v; - | - returning this value requires that `*map` is borrowed for `'1` - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0502`. diff --git a/tests/ui/nll/outlives-suggestion-simple.polonius.stderr b/tests/ui/nll/outlives-suggestion-simple.polonius.stderr deleted file mode 100644 index c00288f2e3c7..000000000000 --- a/tests/ui/nll/outlives-suggestion-simple.polonius.stderr +++ /dev/null @@ -1,124 +0,0 @@ -error: lifetime may not live long enough - --> $DIR/outlives-suggestion-simple.rs:6:5 - | -LL | fn foo1<'a, 'b>(x: &'a usize) -> &'b usize { - | -- -- lifetime `'b` defined here - | | - | lifetime `'a` defined here -LL | x - | ^ returning this value requires that `'a` must outlive `'b` - | - = help: consider adding the following bound: `'a: 'b` - -error: lifetime may not live long enough - --> $DIR/outlives-suggestion-simple.rs:10:5 - | -LL | fn foo2<'a>(x: &'a usize) -> &'static usize { - | -- lifetime `'a` defined here -LL | x - | ^ returning this value requires that `'a` must outlive `'static` - | - = help: consider replacing `'a` with `'static` - -error: lifetime may not live long enough - --> $DIR/outlives-suggestion-simple.rs:14:5 - | -LL | fn foo3<'a, 'b>(x: &'a usize, y: &'b usize) -> (&'b usize, &'a usize) { - | -- -- lifetime `'b` defined here - | | - | lifetime `'a` defined here -LL | (x, y) - | ^^^^^^ function was supposed to return data with lifetime `'b` but it is returning data with lifetime `'a` - | - = help: consider adding the following bound: `'a: 'b` - -error: lifetime may not live long enough - --> $DIR/outlives-suggestion-simple.rs:14:5 - | -LL | fn foo3<'a, 'b>(x: &'a usize, y: &'b usize) -> (&'b usize, &'a usize) { - | -- -- lifetime `'b` defined here - | | - | lifetime `'a` defined here -LL | (x, y) - | ^^^^^^ function was supposed to return data with lifetime `'a` but it is returning data with lifetime `'b` - | - = help: consider adding the following bound: `'b: 'a` - -help: `'a` and `'b` must be the same: replace one with the other - -error: lifetime may not live long enough - --> $DIR/outlives-suggestion-simple.rs:22:5 - | -LL | fn foo4<'a, 'b, 'c>(x: &'a usize) -> (&'b usize, &'c usize) { - | -- -- lifetime `'b` defined here - | | - | lifetime `'a` defined here -... -LL | (x, x) - | ^^^^^^ returning this value requires that `'a` must outlive `'b` - | - = help: consider adding the following bound: `'a: 'b` - -error: lifetime may not live long enough - --> $DIR/outlives-suggestion-simple.rs:22:5 - | -LL | fn foo4<'a, 'b, 'c>(x: &'a usize) -> (&'b usize, &'c usize) { - | -- -- lifetime `'c` defined here - | | - | lifetime `'a` defined here -... -LL | (x, x) - | ^^^^^^ returning this value requires that `'a` must outlive `'c` - | - = help: consider adding the following bound: `'a: 'c` - -help: add bound `'a: 'b + 'c` - -error: lifetime may not live long enough - --> $DIR/outlives-suggestion-simple.rs:31:9 - | -LL | pub fn foo<'a>(x: &'a usize) -> Self { - | -- lifetime `'a` defined here -LL | Foo { x } - | ^^^^^^^^^ returning this value requires that `'a` must outlive `'static` - | - = help: consider replacing `'a` with `'static` - -error: lifetime may not live long enough - --> $DIR/outlives-suggestion-simple.rs:41:9 - | -LL | impl<'a> Bar<'a> { - | -- lifetime `'a` defined here -LL | pub fn get<'b>(&self) -> &'b usize { - | -- lifetime `'b` defined here -LL | self.x - | ^^^^^^ returning this value requires that `'a` must outlive `'b` - | - = help: consider adding the following bound: `'a: 'b` - -error: lifetime may not live long enough - --> $DIR/outlives-suggestion-simple.rs:52:9 - | -LL | impl<'a> Baz<'a> { - | -- lifetime `'a` defined here -LL | fn get<'b>(&'b self) -> &'a i32 { - | -- lifetime `'b` defined here -LL | self.x - | ^^^^^^ returning this value requires that `'b` must outlive `'a` - | - = help: consider adding the following bound: `'b: 'a` - -error[E0521]: borrowed data escapes outside of associated function - --> $DIR/outlives-suggestion-simple.rs:73:9 - | -LL | fn get_bar(&self) -> Bar2 { - | ----- - | | - | `self` declared here, outside of the associated function body - | `self` is a reference that is only valid in the associated function body -LL | Bar2::new(&self) - | ^^^^^^^^^^^^^^^^ `self` escapes the associated function body here - -error: aborting due to 10 previous errors - -For more information about this error, try `rustc --explain E0521`. diff --git a/tests/ui/nll/user-annotations/closure-substs.polonius.stderr b/tests/ui/nll/user-annotations/closure-substs.polonius.stderr deleted file mode 100644 index af159a6cd1b8..000000000000 --- a/tests/ui/nll/user-annotations/closure-substs.polonius.stderr +++ /dev/null @@ -1,61 +0,0 @@ -error: lifetime may not live long enough - --> $DIR/closure-substs.rs:8:16 - | -LL | fn foo<'a>() { - | -- lifetime `'a` defined here -... -LL | return x; - | ^ returning this value requires that `'a` must outlive `'static` - | - = help: consider replacing `'a` with `'static` - -error: lifetime may not live long enough - --> $DIR/closure-substs.rs:15:16 - | -LL | |x: &i32| -> &'static i32 { - | - let's call the lifetime of this reference `'1` -LL | return x; - | ^ returning this value requires that `'1` must outlive `'static` - -error: lifetime may not live long enough - --> $DIR/closure-substs.rs:15:16 - | -LL | |x: &i32| -> &'static i32 { - | - - let's call the lifetime of this reference `'2` - | | - | let's call the lifetime of this reference `'1` -LL | return x; - | ^ returning this value requires that `'1` must outlive `'2` - -error: lifetime may not live long enough - --> $DIR/closure-substs.rs:22:9 - | -LL | fn bar<'a>() { - | -- lifetime `'a` defined here -... -LL | b(x); - | ^^^^ argument requires that `'a` must outlive `'static` - | - = help: consider replacing `'a` with `'static` - -error[E0521]: borrowed data escapes outside of closure - --> $DIR/closure-substs.rs:29:9 - | -LL | |x: &i32, b: fn(&'static i32)| { - | - `x` is a reference that is only valid in the closure body -LL | b(x); - | ^^^^ `x` escapes the closure body here - -error[E0521]: borrowed data escapes outside of closure - --> $DIR/closure-substs.rs:29:9 - | -LL | |x: &i32, b: fn(&'static i32)| { - | - - `b` declared here, outside of the closure body - | | - | `x` is a reference that is only valid in the closure body -LL | b(x); - | ^^^^ `x` escapes the closure body here - -error: aborting due to 6 previous errors - -For more information about this error, try `rustc --explain E0521`. diff --git a/tests/ui/pattern/usefulness/empty-types.min_exh_pats.stderr b/tests/ui/pattern/usefulness/empty-types.min_exh_pats.stderr deleted file mode 100644 index cf37bf67e860..000000000000 --- a/tests/ui/pattern/usefulness/empty-types.min_exh_pats.stderr +++ /dev/null @@ -1,727 +0,0 @@ -error: unreachable pattern - --> $DIR/empty-types.rs:51:9 - | -LL | _ => {} - | ^ - | - = note: this pattern matches no values because `!` is uninhabited -note: the lint level is defined here - --> $DIR/empty-types.rs:17:9 - | -LL | #![deny(unreachable_patterns)] - | ^^^^^^^^^^^^^^^^^^^^ - -error: unreachable pattern - --> $DIR/empty-types.rs:54:9 - | -LL | _x => {} - | ^^ - | - = note: this pattern matches no values because `!` is uninhabited - -error[E0004]: non-exhaustive patterns: type `&!` is non-empty - --> $DIR/empty-types.rs:58:11 - | -LL | match ref_never {} - | ^^^^^^^^^ - | - = note: the matched value is of type `&!` - = note: references are always considered inhabited -help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern as shown - | -LL ~ match ref_never { -LL + _ => todo!(), -LL + } - | - -error: unreachable pattern - --> $DIR/empty-types.rs:73:9 - | -LL | (_, _) => {} - | ^^^^^^ - | - = note: this pattern matches no values because `(u32, !)` is uninhabited - -error: unreachable pattern - --> $DIR/empty-types.rs:80:9 - | -LL | _ => {} - | ^ - | - = note: this pattern matches no values because `(!, !)` is uninhabited - -error: unreachable pattern - --> $DIR/empty-types.rs:83:9 - | -LL | (_, _) => {} - | ^^^^^^ - | - = note: this pattern matches no values because `(!, !)` is uninhabited - -error: unreachable pattern - --> $DIR/empty-types.rs:87:9 - | -LL | _ => {} - | ^ - | - = note: this pattern matches no values because `!` is uninhabited - -error[E0004]: non-exhaustive patterns: `Ok(_)` not covered - --> $DIR/empty-types.rs:91:11 - | -LL | match res_u32_never {} - | ^^^^^^^^^^^^^ pattern `Ok(_)` not covered - | -note: `Result` defined here - --> $SRC_DIR/core/src/result.rs:LL:COL - ::: $SRC_DIR/core/src/result.rs:LL:COL - | - = note: not covered - = note: the matched value is of type `Result` -help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown - | -LL ~ match res_u32_never { -LL + Ok(_) => todo!(), -LL + } - | - -error: unreachable pattern - --> $DIR/empty-types.rs:99:9 - | -LL | Err(_) => {} - | ^^^^^^ - | - = note: this pattern matches no values because `!` is uninhabited - -error: unreachable pattern - --> $DIR/empty-types.rs:104:9 - | -LL | Err(_) => {} - | ^^^^^^ - | - = note: this pattern matches no values because `!` is uninhabited - -error[E0004]: non-exhaustive patterns: `Ok(1_u32..=u32::MAX)` not covered - --> $DIR/empty-types.rs:101:11 - | -LL | match res_u32_never { - | ^^^^^^^^^^^^^ pattern `Ok(1_u32..=u32::MAX)` not covered - | -note: `Result` defined here - --> $SRC_DIR/core/src/result.rs:LL:COL - ::: $SRC_DIR/core/src/result.rs:LL:COL - | - = note: not covered - = note: the matched value is of type `Result` -help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown - | -LL ~ Err(_) => {}, -LL ~ Ok(1_u32..=u32::MAX) => todo!() - | - -error[E0005]: refutable pattern in local binding - --> $DIR/empty-types.rs:108:9 - | -LL | let Ok(_x) = res_u32_never.as_ref(); - | ^^^^^^ pattern `Err(_)` not covered - | - = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant - = note: for more information, visit https://doc.rust-lang.org/book/ch19-02-refutability.html - = note: the matched value is of type `Result<&u32, &!>` -help: you might want to use `let else` to handle the variant that isn't matched - | -LL | let Ok(_x) = res_u32_never.as_ref() else { todo!() }; - | ++++++++++++++++ - -error[E0005]: refutable pattern in local binding - --> $DIR/empty-types.rs:112:9 - | -LL | let Ok(_x) = &res_u32_never; - | ^^^^^^ pattern `&Err(_)` not covered - | - = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant - = note: for more information, visit https://doc.rust-lang.org/book/ch19-02-refutability.html - = note: the matched value is of type `&Result` -help: you might want to use `let else` to handle the variant that isn't matched - | -LL | let Ok(_x) = &res_u32_never else { todo!() }; - | ++++++++++++++++ - -error: unreachable pattern - --> $DIR/empty-types.rs:119:9 - | -LL | _ => {} - | ^ - | - = note: this pattern matches no values because `Result` is uninhabited - -error: unreachable pattern - --> $DIR/empty-types.rs:123:9 - | -LL | Ok(_) => {} - | ^^^^^ - | - = note: this pattern matches no values because `Result` is uninhabited - -error: unreachable pattern - --> $DIR/empty-types.rs:126:9 - | -LL | Ok(_) => {} - | ^^^^^ - | - = note: this pattern matches no values because `Result` is uninhabited - -error: unreachable pattern - --> $DIR/empty-types.rs:127:9 - | -LL | _ => {} - | ^ - | - = note: this pattern matches no values because `Result` is uninhabited - -error: unreachable pattern - --> $DIR/empty-types.rs:130:9 - | -LL | Ok(_) => {} - | ^^^^^ - | - = note: this pattern matches no values because `Result` is uninhabited - -error: unreachable pattern - --> $DIR/empty-types.rs:131:9 - | -LL | Err(_) => {} - | ^^^^^^ - | - = note: this pattern matches no values because `Result` is uninhabited - -error: unreachable pattern - --> $DIR/empty-types.rs:140:13 - | -LL | _ => {} - | ^ - | - = note: this pattern matches no values because `Void` is uninhabited - -error: unreachable pattern - --> $DIR/empty-types.rs:143:13 - | -LL | _ if false => {} - | ^ - | - = note: this pattern matches no values because `Void` is uninhabited - -error: unreachable pattern - --> $DIR/empty-types.rs:152:13 - | -LL | Some(_) => {} - | ^^^^^^^ - | - = note: this pattern matches no values because `Void` is uninhabited - -error: unreachable pattern - --> $DIR/empty-types.rs:156:13 - | -LL | None => {} - | ---- matches all the values already -LL | _ => {} - | ^ unreachable pattern - -error[E0004]: non-exhaustive patterns: `Some(_)` not covered - --> $DIR/empty-types.rs:165:15 - | -LL | match *ref_opt_void { - | ^^^^^^^^^^^^^ pattern `Some(_)` not covered - | -note: `Option` defined here - --> $SRC_DIR/core/src/option.rs:LL:COL - ::: $SRC_DIR/core/src/option.rs:LL:COL - | - = note: not covered - = note: the matched value is of type `Option` - = note: `Void` is uninhabited but is not being matched by value, so a wildcard `_` is required -help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown - | -LL ~ None => {}, -LL + Some(_) => todo!() - | - -error: unreachable pattern - --> $DIR/empty-types.rs:208:13 - | -LL | _ => {} - | ^ - | - = note: this pattern matches no values because `!` is uninhabited - -error: unreachable pattern - --> $DIR/empty-types.rs:213:13 - | -LL | _ => {} - | ^ - | - = note: this pattern matches no values because `!` is uninhabited - -error: unreachable pattern - --> $DIR/empty-types.rs:218:13 - | -LL | _ => {} - | ^ - | - = note: this pattern matches no values because `!` is uninhabited - -error: unreachable pattern - --> $DIR/empty-types.rs:223:13 - | -LL | _ => {} - | ^ - | - = note: this pattern matches no values because `!` is uninhabited - -error: unreachable pattern - --> $DIR/empty-types.rs:229:13 - | -LL | _ => {} - | ^ - | - = note: this pattern matches no values because `!` is uninhabited - -error: unreachable pattern - --> $DIR/empty-types.rs:288:9 - | -LL | _ => {} - | ^ - | - = note: this pattern matches no values because `!` is uninhabited - -error: unreachable pattern - --> $DIR/empty-types.rs:291:9 - | -LL | (_, _) => {} - | ^^^^^^ - | - = note: this pattern matches no values because `(!, !)` is uninhabited - -error: unreachable pattern - --> $DIR/empty-types.rs:294:9 - | -LL | Ok(_) => {} - | ^^^^^ - | - = note: this pattern matches no values because `Result` is uninhabited - -error: unreachable pattern - --> $DIR/empty-types.rs:295:9 - | -LL | Err(_) => {} - | ^^^^^^ - | - = note: this pattern matches no values because `Result` is uninhabited - -error[E0004]: non-exhaustive patterns: type `(u32, !)` is non-empty - --> $DIR/empty-types.rs:316:11 - | -LL | match *x {} - | ^^ - | - = note: the matched value is of type `(u32, !)` -help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern as shown - | -LL ~ match *x { -LL + _ => todo!(), -LL ~ } - | - -error[E0004]: non-exhaustive patterns: type `(!, !)` is non-empty - --> $DIR/empty-types.rs:318:11 - | -LL | match *x {} - | ^^ - | - = note: the matched value is of type `(!, !)` -help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern as shown - | -LL ~ match *x { -LL + _ => todo!(), -LL ~ } - | - -error[E0004]: non-exhaustive patterns: `Ok(_)` and `Err(_)` not covered - --> $DIR/empty-types.rs:320:11 - | -LL | match *x {} - | ^^ patterns `Ok(_)` and `Err(_)` not covered - | -note: `Result` defined here - --> $SRC_DIR/core/src/result.rs:LL:COL - ::: $SRC_DIR/core/src/result.rs:LL:COL - | - = note: not covered - ::: $SRC_DIR/core/src/result.rs:LL:COL - | - = note: not covered - = note: the matched value is of type `Result` -help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern, a match arm with multiple or-patterns as shown, or multiple match arms - | -LL ~ match *x { -LL + Ok(_) | Err(_) => todo!(), -LL ~ } - | - -error[E0004]: non-exhaustive patterns: type `[!; 3]` is non-empty - --> $DIR/empty-types.rs:322:11 - | -LL | match *x {} - | ^^ - | - = note: the matched value is of type `[!; 3]` -help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern as shown - | -LL ~ match *x { -LL + _ => todo!(), -LL ~ } - | - -error[E0004]: non-exhaustive patterns: type `&[!]` is non-empty - --> $DIR/empty-types.rs:327:11 - | -LL | match slice_never {} - | ^^^^^^^^^^^ - | - = note: the matched value is of type `&[!]` -help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern as shown - | -LL ~ match slice_never { -LL + _ => todo!(), -LL + } - | - -error[E0004]: non-exhaustive patterns: `&[_, ..]` not covered - --> $DIR/empty-types.rs:329:11 - | -LL | match slice_never { - | ^^^^^^^^^^^ pattern `&[_, ..]` not covered - | - = note: the matched value is of type `&[!]` - = note: `!` is uninhabited but is not being matched by value, so a wildcard `_` is required -help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown - | -LL ~ [] => {}, -LL + &[_, ..] => todo!() - | - -error[E0004]: non-exhaustive patterns: `&[]`, `&[_]` and `&[_, _]` not covered - --> $DIR/empty-types.rs:338:11 - | -LL | match slice_never { - | ^^^^^^^^^^^ patterns `&[]`, `&[_]` and `&[_, _]` not covered - | - = note: the matched value is of type `&[!]` -help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern, a match arm with multiple or-patterns as shown, or multiple match arms - | -LL ~ [_, _, _, ..] => {}, -LL + &[] | &[_] | &[_, _] => todo!() - | - -error[E0004]: non-exhaustive patterns: `&[]` and `&[_, ..]` not covered - --> $DIR/empty-types.rs:352:11 - | -LL | match slice_never { - | ^^^^^^^^^^^ patterns `&[]` and `&[_, ..]` not covered - | - = note: the matched value is of type `&[!]` - = note: match arms with guards don't count towards exhaustivity -help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern, a match arm with multiple or-patterns as shown, or multiple match arms - | -LL ~ &[..] if false => {}, -LL + &[] | &[_, ..] => todo!() - | - -error[E0004]: non-exhaustive patterns: type `[!]` is non-empty - --> $DIR/empty-types.rs:359:11 - | -LL | match *slice_never {} - | ^^^^^^^^^^^^ - | - = note: the matched value is of type `[!]` -help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern as shown - | -LL ~ match *slice_never { -LL + _ => todo!(), -LL + } - | - -error: unreachable pattern - --> $DIR/empty-types.rs:369:9 - | -LL | _ => {} - | ^ - | - = note: this pattern matches no values because `[!; 3]` is uninhabited - -error: unreachable pattern - --> $DIR/empty-types.rs:372:9 - | -LL | [_, _, _] => {} - | ^^^^^^^^^ - | - = note: this pattern matches no values because `[!; 3]` is uninhabited - -error: unreachable pattern - --> $DIR/empty-types.rs:375:9 - | -LL | [_, ..] => {} - | ^^^^^^^ - | - = note: this pattern matches no values because `[!; 3]` is uninhabited - -error[E0004]: non-exhaustive patterns: type `[!; 0]` is non-empty - --> $DIR/empty-types.rs:389:11 - | -LL | match array_0_never {} - | ^^^^^^^^^^^^^ - | - = note: the matched value is of type `[!; 0]` -help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern as shown - | -LL ~ match array_0_never { -LL + _ => todo!(), -LL + } - | - -error: unreachable pattern - --> $DIR/empty-types.rs:396:9 - | -LL | [] => {} - | -- matches all the values already -LL | _ => {} - | ^ unreachable pattern - -error[E0004]: non-exhaustive patterns: `[]` not covered - --> $DIR/empty-types.rs:398:11 - | -LL | match array_0_never { - | ^^^^^^^^^^^^^ pattern `[]` not covered - | - = note: the matched value is of type `[!; 0]` - = note: match arms with guards don't count towards exhaustivity -help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown - | -LL ~ [..] if false => {}, -LL + [] => todo!() - | - -error: unreachable pattern - --> $DIR/empty-types.rs:417:9 - | -LL | Some(_) => {} - | ^^^^^^^ - | - = note: this pattern matches no values because `!` is uninhabited - -error: unreachable pattern - --> $DIR/empty-types.rs:422:9 - | -LL | Some(_a) => {} - | ^^^^^^^^ - | - = note: this pattern matches no values because `!` is uninhabited - -error: unreachable pattern - --> $DIR/empty-types.rs:427:9 - | -LL | None => {} - | ---- matches all the values already -LL | // !useful, !reachable -LL | _ => {} - | ^ unreachable pattern - -error: unreachable pattern - --> $DIR/empty-types.rs:432:9 - | -LL | None => {} - | ---- matches all the values already -LL | // !useful, !reachable -LL | _a => {} - | ^^ unreachable pattern - -error[E0004]: non-exhaustive patterns: `&Some(_)` not covered - --> $DIR/empty-types.rs:452:11 - | -LL | match ref_opt_never { - | ^^^^^^^^^^^^^ pattern `&Some(_)` not covered - | -note: `Option` defined here - --> $SRC_DIR/core/src/option.rs:LL:COL - ::: $SRC_DIR/core/src/option.rs:LL:COL - | - = note: not covered - = note: the matched value is of type `&Option` - = note: `!` is uninhabited but is not being matched by value, so a wildcard `_` is required -help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown - | -LL ~ &None => {}, -LL + &Some(_) => todo!() - | - -error[E0004]: non-exhaustive patterns: `Some(_)` not covered - --> $DIR/empty-types.rs:493:11 - | -LL | match *ref_opt_never { - | ^^^^^^^^^^^^^^ pattern `Some(_)` not covered - | -note: `Option` defined here - --> $SRC_DIR/core/src/option.rs:LL:COL - ::: $SRC_DIR/core/src/option.rs:LL:COL - | - = note: not covered - = note: the matched value is of type `Option` - = note: `!` is uninhabited but is not being matched by value, so a wildcard `_` is required -help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown - | -LL ~ None => {}, -LL + Some(_) => todo!() - | - -error[E0004]: non-exhaustive patterns: `Err(_)` not covered - --> $DIR/empty-types.rs:541:11 - | -LL | match *ref_res_never { - | ^^^^^^^^^^^^^^ pattern `Err(_)` not covered - | -note: `Result` defined here - --> $SRC_DIR/core/src/result.rs:LL:COL - ::: $SRC_DIR/core/src/result.rs:LL:COL - | - = note: not covered - = note: the matched value is of type `Result` - = note: `!` is uninhabited but is not being matched by value, so a wildcard `_` is required -help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown - | -LL ~ Ok(_) => {}, -LL + Err(_) => todo!() - | - -error[E0004]: non-exhaustive patterns: `Err(_)` not covered - --> $DIR/empty-types.rs:552:11 - | -LL | match *ref_res_never { - | ^^^^^^^^^^^^^^ pattern `Err(_)` not covered - | -note: `Result` defined here - --> $SRC_DIR/core/src/result.rs:LL:COL - ::: $SRC_DIR/core/src/result.rs:LL:COL - | - = note: not covered - = note: the matched value is of type `Result` - = note: `!` is uninhabited but is not being matched by value, so a wildcard `_` is required -help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown - | -LL ~ Ok(_a) => {}, -LL + Err(_) => todo!() - | - -error[E0004]: non-exhaustive patterns: type `(u32, !)` is non-empty - --> $DIR/empty-types.rs:571:11 - | -LL | match *ref_tuple_half_never {} - | ^^^^^^^^^^^^^^^^^^^^^ - | - = note: the matched value is of type `(u32, !)` -help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern as shown - | -LL ~ match *ref_tuple_half_never { -LL + _ => todo!(), -LL + } - | - -error: unreachable pattern - --> $DIR/empty-types.rs:604:9 - | -LL | _ => {} - | ^ - | - = note: this pattern matches no values because `!` is uninhabited - -error: unreachable pattern - --> $DIR/empty-types.rs:607:9 - | -LL | _x => {} - | ^^ - | - = note: this pattern matches no values because `!` is uninhabited - -error: unreachable pattern - --> $DIR/empty-types.rs:610:9 - | -LL | _ if false => {} - | ^ - | - = note: this pattern matches no values because `!` is uninhabited - -error: unreachable pattern - --> $DIR/empty-types.rs:613:9 - | -LL | _x if false => {} - | ^^ - | - = note: this pattern matches no values because `!` is uninhabited - -error[E0004]: non-exhaustive patterns: `&_` not covered - --> $DIR/empty-types.rs:638:11 - | -LL | match ref_never { - | ^^^^^^^^^ pattern `&_` not covered - | - = note: the matched value is of type `&!` - = note: `!` is uninhabited but is not being matched by value, so a wildcard `_` is required - = note: references are always considered inhabited - = note: match arms with guards don't count towards exhaustivity -help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown - | -LL ~ &_a if false => {}, -LL + &_ => todo!() - | - -error[E0004]: non-exhaustive patterns: `Ok(_)` not covered - --> $DIR/empty-types.rs:654:11 - | -LL | match *ref_result_never { - | ^^^^^^^^^^^^^^^^^ pattern `Ok(_)` not covered - | -note: `Result` defined here - --> $SRC_DIR/core/src/result.rs:LL:COL - ::: $SRC_DIR/core/src/result.rs:LL:COL - | - = note: not covered - = note: the matched value is of type `Result` - = note: `!` is uninhabited but is not being matched by value, so a wildcard `_` is required -help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown - | -LL ~ Err(_) => {}, -LL + Ok(_) => todo!() - | - -error[E0004]: non-exhaustive patterns: `Some(_)` not covered - --> $DIR/empty-types.rs:674:11 - | -LL | match *x { - | ^^ pattern `Some(_)` not covered - | -note: `Option>` defined here - --> $SRC_DIR/core/src/option.rs:LL:COL - ::: $SRC_DIR/core/src/option.rs:LL:COL - | - = note: not covered - = note: the matched value is of type `Option>` - = note: `Result` is uninhabited but is not being matched by value, so a wildcard `_` is required -help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown - | -LL ~ None => {}, -LL + Some(_) => todo!() - | - -error: aborting due to 64 previous errors - -Some errors have detailed explanations: E0004, E0005. -For more information about an error, try `rustc --explain E0004`. diff --git a/tests/ui/pattern/usefulness/match-privately-empty.min_exhaustive_patterns.stderr b/tests/ui/pattern/usefulness/match-privately-empty.min_exhaustive_patterns.stderr deleted file mode 100644 index 261a4b3353f2..000000000000 --- a/tests/ui/pattern/usefulness/match-privately-empty.min_exhaustive_patterns.stderr +++ /dev/null @@ -1,21 +0,0 @@ -error[E0004]: non-exhaustive patterns: `Some(Private { misc: true, .. })` not covered - --> $DIR/match-privately-empty.rs:15:11 - | -LL | match private::DATA { - | ^^^^^^^^^^^^^ pattern `Some(Private { misc: true, .. })` not covered - | -note: `Option` defined here - --> $SRC_DIR/core/src/option.rs:LL:COL - ::: $SRC_DIR/core/src/option.rs:LL:COL - | - = note: not covered - = note: the matched value is of type `Option` -help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown - | -LL ~ Some(private::Private { misc: false, .. }) => {}, -LL + Some(Private { misc: true, .. }) => todo!() - | - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0004`. diff --git a/tests/ui/pattern/usefulness/slice_of_empty.min_exhaustive_patterns.stderr b/tests/ui/pattern/usefulness/slice_of_empty.min_exhaustive_patterns.stderr deleted file mode 100644 index f24ce154d149..000000000000 --- a/tests/ui/pattern/usefulness/slice_of_empty.min_exhaustive_patterns.stderr +++ /dev/null @@ -1,30 +0,0 @@ -error[E0004]: non-exhaustive patterns: `&[_, ..]` not covered - --> $DIR/slice_of_empty.rs:10:11 - | -LL | match nevers { - | ^^^^^^ pattern `&[_, ..]` not covered - | - = note: the matched value is of type `&[!]` - = note: `!` is uninhabited but is not being matched by value, so a wildcard `_` is required -help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown - | -LL ~ &[] => (), -LL ~ &[_, ..] => todo!(), - | - -error[E0004]: non-exhaustive patterns: `&[]` and `&[_, _, ..]` not covered - --> $DIR/slice_of_empty.rs:21:11 - | -LL | match nevers { - | ^^^^^^ patterns `&[]` and `&[_, _, ..]` not covered - | - = note: the matched value is of type `&[!]` -help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern, a match arm with multiple or-patterns as shown, or multiple match arms - | -LL ~ &[_] => (), -LL ~ &[] | &[_, _, ..] => todo!(), - | - -error: aborting due to 2 previous errors - -For more information about this error, try `rustc --explain E0004`. diff --git a/tests/ui/recursion/issue-38591-non-regular-dropck-recursion.polonius.stderr b/tests/ui/recursion/issue-38591-non-regular-dropck-recursion.polonius.stderr deleted file mode 100644 index ff1a127e63e3..000000000000 --- a/tests/ui/recursion/issue-38591-non-regular-dropck-recursion.polonius.stderr +++ /dev/null @@ -1,15 +0,0 @@ -error: reached the recursion limit while instantiating `std::ptr::drop_in_place::))` - --> $SRC_DIR/core/src/ptr/mod.rs:LL:COL - | -LL | pub unsafe fn drop_in_place(to_drop: *mut T) { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | -note: `std::ptr::drop_in_place` defined here - --> $SRC_DIR/core/src/ptr/mod.rs:LL:COL - | -LL | pub unsafe fn drop_in_place(to_drop: *mut T) { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - = note: the full type name has been written to '$TEST_BUILD_DIR/recursion/issue-38591-non-regular-dropck-recursion.polonius/issue-38591-non-regular-dropck-recursion.long-type.txt' - -error: aborting due to 1 previous error - diff --git a/tests/ui/recursion/recursion.polonius.stderr b/tests/ui/recursion/recursion.polonius.stderr deleted file mode 100644 index 737e71e88451..000000000000 --- a/tests/ui/recursion/recursion.polonius.stderr +++ /dev/null @@ -1,15 +0,0 @@ -error: reached the recursion limit while instantiating `test::>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>` - --> $DIR/recursion.rs:18:11 - | -LL | _ => {test (n-1, i+1, Cons {head:2*i+1, tail:first}, Cons{head:i*i, tail:second})} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | -note: `test` defined here - --> $DIR/recursion.rs:16:1 - | -LL | fn test (n:isize, i:isize, first:T, second:T) ->isize { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - = note: the full type name has been written to '$TEST_BUILD_DIR/recursion/recursion.polonius/recursion.long-type.txt' - -error: aborting due to 1 previous error - diff --git a/tests/ui/rfcs/rfc-0000-never_patterns/unreachable.exh_pats.stderr b/tests/ui/rfcs/rfc-0000-never_patterns/unreachable.exh_pats.stderr deleted file mode 100644 index d78f4a5f6ebb..000000000000 --- a/tests/ui/rfcs/rfc-0000-never_patterns/unreachable.exh_pats.stderr +++ /dev/null @@ -1,55 +0,0 @@ -error: unreachable pattern - --> $DIR/unreachable.rs:16:9 - | -LL | Err(!), - | ^^^^^^ - | - = note: this pattern matches no values because `Void` is uninhabited -note: the lint level is defined here - --> $DIR/unreachable.rs:6:9 - | -LL | #![deny(unreachable_patterns)] - | ^^^^^^^^^^^^^^^^^^^^ - -error: unreachable pattern - --> $DIR/unreachable.rs:19:19 - | -LL | let (Ok(_x) | Err(!)) = res_void; - | ^^^^^^ - | - = note: this pattern matches no values because `Void` is uninhabited - -error: unreachable pattern - --> $DIR/unreachable.rs:21:12 - | -LL | if let Err(!) = res_void {} - | ^^^^^^ - | - = note: this pattern matches no values because `Void` is uninhabited - -error: unreachable pattern - --> $DIR/unreachable.rs:23:24 - | -LL | if let (Ok(true) | Err(!)) = res_void {} - | ^^^^^^ - | - = note: this pattern matches no values because `Void` is uninhabited - -error: unreachable pattern - --> $DIR/unreachable.rs:25:23 - | -LL | for (Ok(mut _x) | Err(!)) in [res_void] {} - | ^^^^^^ - | - = note: this pattern matches no values because `Void` is uninhabited - -error: unreachable pattern - --> $DIR/unreachable.rs:29:18 - | -LL | fn foo((Ok(_x) | Err(!)): Result) {} - | ^^^^^^ - | - = note: this pattern matches no values because `Void` is uninhabited - -error: aborting due to 6 previous errors - diff --git a/tests/ui/rfcs/rfc-0000-never_patterns/unreachable.normal.stderr b/tests/ui/rfcs/rfc-0000-never_patterns/unreachable.normal.stderr deleted file mode 100644 index a3bf8e80ecec..000000000000 --- a/tests/ui/rfcs/rfc-0000-never_patterns/unreachable.normal.stderr +++ /dev/null @@ -1,44 +0,0 @@ -error: unreachable pattern - --> $DIR/unreachable.rs:16:9 - | -LL | Err(!), - | ^^^^^^ - | -note: the lint level is defined here - --> $DIR/unreachable.rs:6:9 - | -LL | #![deny(unreachable_patterns)] - | ^^^^^^^^^^^^^^^^^^^^ - -error: unreachable pattern - --> $DIR/unreachable.rs:19:19 - | -LL | let (Ok(_x) | Err(!)) = res_void; - | ^^^^^^ - -error: unreachable pattern - --> $DIR/unreachable.rs:21:12 - | -LL | if let Err(!) = res_void {} - | ^^^^^^ - -error: unreachable pattern - --> $DIR/unreachable.rs:23:24 - | -LL | if let (Ok(true) | Err(!)) = res_void {} - | ^^^^^^ - -error: unreachable pattern - --> $DIR/unreachable.rs:25:23 - | -LL | for (Ok(mut _x) | Err(!)) in [res_void] {} - | ^^^^^^ - -error: unreachable pattern - --> $DIR/unreachable.rs:29:18 - | -LL | fn foo((Ok(_x) | Err(!)): Result) {} - | ^^^^^^ - -error: aborting due to 6 previous errors - diff --git a/tests/ui/rfcs/rfc-1937-termination-trait/issue-103052-2.current.stderr b/tests/ui/rfcs/rfc-1937-termination-trait/issue-103052-2.current.stderr deleted file mode 100644 index f2727336bc56..000000000000 --- a/tests/ui/rfcs/rfc-1937-termination-trait/issue-103052-2.current.stderr +++ /dev/null @@ -1,15 +0,0 @@ -error[E0277]: the trait bound `Something: Termination` is not satisfied - --> $DIR/issue-103052-2.rs:15:22 - | -LL | fn main() -> Something { - | ^^^^^^^^^ the trait `Termination` is not implemented for `Something` - | -note: required by a bound in `Main::main::{opaque#0}` - --> $DIR/issue-103052-2.rs:9:27 - | -LL | fn main() -> impl std::process::Termination; - | ^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `Main::main::{opaque#0}` - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/rfcs/rfc-1937-termination-trait/issue-103052-2.next.stderr b/tests/ui/rfcs/rfc-1937-termination-trait/issue-103052-2.next.stderr deleted file mode 100644 index 4bb420664f7f..000000000000 --- a/tests/ui/rfcs/rfc-1937-termination-trait/issue-103052-2.next.stderr +++ /dev/null @@ -1,15 +0,0 @@ -error[E0277]: the trait bound `Something: Termination` is not satisfied - --> $DIR/issue-103052-2.rs:15:22 - | -LL | fn main() -> Something { - | ^^^^^^^^^ the trait `Termination` is not implemented for `Something` - | -note: required by a bound in `Main::{opaque#0}` - --> $DIR/issue-103052-2.rs:9:27 - | -LL | fn main() -> impl std::process::Termination; - | ^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `Main::{opaque#0}` - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/rfcs/rfc-2497-if-let-chains/disallowed-positions.nofeature.stderr b/tests/ui/rfcs/rfc-2497-if-let-chains/disallowed-positions.nofeature.stderr deleted file mode 100644 index f556ecf7f91d..000000000000 --- a/tests/ui/rfcs/rfc-2497-if-let-chains/disallowed-positions.nofeature.stderr +++ /dev/null @@ -1,1111 +0,0 @@ -error: expected expression, found `let` statement - --> $DIR/disallowed-positions.rs:31:9 - | -LL | if (let 0 = 1) {} - | ^^^^^^^^^ - | - = note: only supported directly in conditions of `if` and `while` expressions -note: `let`s wrapped in parentheses are not supported in a context with let chains - --> $DIR/disallowed-positions.rs:31:9 - | -LL | if (let 0 = 1) {} - | ^^^^^^^^^ - -error: expected expression, found `let` statement - --> $DIR/disallowed-positions.rs:34:11 - | -LL | if (((let 0 = 1))) {} - | ^^^^^^^^^ - | - = note: only supported directly in conditions of `if` and `while` expressions -note: `let`s wrapped in parentheses are not supported in a context with let chains - --> $DIR/disallowed-positions.rs:34:11 - | -LL | if (((let 0 = 1))) {} - | ^^^^^^^^^ - -error: expected expression, found `let` statement - --> $DIR/disallowed-positions.rs:37:9 - | -LL | if (let 0 = 1) && true {} - | ^^^^^^^^^ - | - = note: only supported directly in conditions of `if` and `while` expressions -note: `let`s wrapped in parentheses are not supported in a context with let chains - --> $DIR/disallowed-positions.rs:37:9 - | -LL | if (let 0 = 1) && true {} - | ^^^^^^^^^ - -error: expected expression, found `let` statement - --> $DIR/disallowed-positions.rs:40:17 - | -LL | if true && (let 0 = 1) {} - | ^^^^^^^^^ - | - = note: only supported directly in conditions of `if` and `while` expressions -note: `let`s wrapped in parentheses are not supported in a context with let chains - --> $DIR/disallowed-positions.rs:40:17 - | -LL | if true && (let 0 = 1) {} - | ^^^^^^^^^ - -error: expected expression, found `let` statement - --> $DIR/disallowed-positions.rs:43:9 - | -LL | if (let 0 = 1) && (let 0 = 1) {} - | ^^^^^^^^^ - | - = note: only supported directly in conditions of `if` and `while` expressions -note: `let`s wrapped in parentheses are not supported in a context with let chains - --> $DIR/disallowed-positions.rs:43:9 - | -LL | if (let 0 = 1) && (let 0 = 1) {} - | ^^^^^^^^^ - -error: expected expression, found `let` statement - --> $DIR/disallowed-positions.rs:43:24 - | -LL | if (let 0 = 1) && (let 0 = 1) {} - | ^^^^^^^^^ - | - = note: only supported directly in conditions of `if` and `while` expressions -note: `let`s wrapped in parentheses are not supported in a context with let chains - --> $DIR/disallowed-positions.rs:43:24 - | -LL | if (let 0 = 1) && (let 0 = 1) {} - | ^^^^^^^^^ - -error: expected expression, found `let` statement - --> $DIR/disallowed-positions.rs:47:35 - | -LL | if let 0 = 1 && let 1 = 2 && (let 2 = 3 && let 3 = 4 && let 4 = 5) {} - | ^^^^^^^^^ - | - = note: only supported directly in conditions of `if` and `while` expressions -note: `let`s wrapped in parentheses are not supported in a context with let chains - --> $DIR/disallowed-positions.rs:47:35 - | -LL | if let 0 = 1 && let 1 = 2 && (let 2 = 3 && let 3 = 4 && let 4 = 5) {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -error: expected expression, found `let` statement - --> $DIR/disallowed-positions.rs:47:48 - | -LL | if let 0 = 1 && let 1 = 2 && (let 2 = 3 && let 3 = 4 && let 4 = 5) {} - | ^^^^^^^^^ - | - = note: only supported directly in conditions of `if` and `while` expressions -note: `let`s wrapped in parentheses are not supported in a context with let chains - --> $DIR/disallowed-positions.rs:47:35 - | -LL | if let 0 = 1 && let 1 = 2 && (let 2 = 3 && let 3 = 4 && let 4 = 5) {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -error: expected expression, found `let` statement - --> $DIR/disallowed-positions.rs:47:61 - | -LL | if let 0 = 1 && let 1 = 2 && (let 2 = 3 && let 3 = 4 && let 4 = 5) {} - | ^^^^^^^^^ - | - = note: only supported directly in conditions of `if` and `while` expressions -note: `let`s wrapped in parentheses are not supported in a context with let chains - --> $DIR/disallowed-positions.rs:47:35 - | -LL | if let 0 = 1 && let 1 = 2 && (let 2 = 3 && let 3 = 4 && let 4 = 5) {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -error: expected expression, found `let` statement - --> $DIR/disallowed-positions.rs:56:12 - | -LL | while (let 0 = 1) {} - | ^^^^^^^^^ - | - = note: only supported directly in conditions of `if` and `while` expressions -note: `let`s wrapped in parentheses are not supported in a context with let chains - --> $DIR/disallowed-positions.rs:56:12 - | -LL | while (let 0 = 1) {} - | ^^^^^^^^^ - -error: expected expression, found `let` statement - --> $DIR/disallowed-positions.rs:59:14 - | -LL | while (((let 0 = 1))) {} - | ^^^^^^^^^ - | - = note: only supported directly in conditions of `if` and `while` expressions -note: `let`s wrapped in parentheses are not supported in a context with let chains - --> $DIR/disallowed-positions.rs:59:14 - | -LL | while (((let 0 = 1))) {} - | ^^^^^^^^^ - -error: expected expression, found `let` statement - --> $DIR/disallowed-positions.rs:62:12 - | -LL | while (let 0 = 1) && true {} - | ^^^^^^^^^ - | - = note: only supported directly in conditions of `if` and `while` expressions -note: `let`s wrapped in parentheses are not supported in a context with let chains - --> $DIR/disallowed-positions.rs:62:12 - | -LL | while (let 0 = 1) && true {} - | ^^^^^^^^^ - -error: expected expression, found `let` statement - --> $DIR/disallowed-positions.rs:65:20 - | -LL | while true && (let 0 = 1) {} - | ^^^^^^^^^ - | - = note: only supported directly in conditions of `if` and `while` expressions -note: `let`s wrapped in parentheses are not supported in a context with let chains - --> $DIR/disallowed-positions.rs:65:20 - | -LL | while true && (let 0 = 1) {} - | ^^^^^^^^^ - -error: expected expression, found `let` statement - --> $DIR/disallowed-positions.rs:68:12 - | -LL | while (let 0 = 1) && (let 0 = 1) {} - | ^^^^^^^^^ - | - = note: only supported directly in conditions of `if` and `while` expressions -note: `let`s wrapped in parentheses are not supported in a context with let chains - --> $DIR/disallowed-positions.rs:68:12 - | -LL | while (let 0 = 1) && (let 0 = 1) {} - | ^^^^^^^^^ - -error: expected expression, found `let` statement - --> $DIR/disallowed-positions.rs:68:27 - | -LL | while (let 0 = 1) && (let 0 = 1) {} - | ^^^^^^^^^ - | - = note: only supported directly in conditions of `if` and `while` expressions -note: `let`s wrapped in parentheses are not supported in a context with let chains - --> $DIR/disallowed-positions.rs:68:27 - | -LL | while (let 0 = 1) && (let 0 = 1) {} - | ^^^^^^^^^ - -error: expected expression, found `let` statement - --> $DIR/disallowed-positions.rs:72:38 - | -LL | while let 0 = 1 && let 1 = 2 && (let 2 = 3 && let 3 = 4 && let 4 = 5) {} - | ^^^^^^^^^ - | - = note: only supported directly in conditions of `if` and `while` expressions -note: `let`s wrapped in parentheses are not supported in a context with let chains - --> $DIR/disallowed-positions.rs:72:38 - | -LL | while let 0 = 1 && let 1 = 2 && (let 2 = 3 && let 3 = 4 && let 4 = 5) {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -error: expected expression, found `let` statement - --> $DIR/disallowed-positions.rs:72:51 - | -LL | while let 0 = 1 && let 1 = 2 && (let 2 = 3 && let 3 = 4 && let 4 = 5) {} - | ^^^^^^^^^ - | - = note: only supported directly in conditions of `if` and `while` expressions -note: `let`s wrapped in parentheses are not supported in a context with let chains - --> $DIR/disallowed-positions.rs:72:38 - | -LL | while let 0 = 1 && let 1 = 2 && (let 2 = 3 && let 3 = 4 && let 4 = 5) {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -error: expected expression, found `let` statement - --> $DIR/disallowed-positions.rs:72:64 - | -LL | while let 0 = 1 && let 1 = 2 && (let 2 = 3 && let 3 = 4 && let 4 = 5) {} - | ^^^^^^^^^ - | - = note: only supported directly in conditions of `if` and `while` expressions -note: `let`s wrapped in parentheses are not supported in a context with let chains - --> $DIR/disallowed-positions.rs:72:38 - | -LL | while let 0 = 1 && let 1 = 2 && (let 2 = 3 && let 3 = 4 && let 4 = 5) {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -error: expected expression, found `let` statement - --> $DIR/disallowed-positions.rs:95:9 - | -LL | if &let 0 = 0 {} - | ^^^^^^^^^ - | - = note: only supported directly in conditions of `if` and `while` expressions - -error: expected expression, found `let` statement - --> $DIR/disallowed-positions.rs:98:9 - | -LL | if !let 0 = 0 {} - | ^^^^^^^^^ - | - = note: only supported directly in conditions of `if` and `while` expressions - -error: expected expression, found `let` statement - --> $DIR/disallowed-positions.rs:100:9 - | -LL | if *let 0 = 0 {} - | ^^^^^^^^^ - | - = note: only supported directly in conditions of `if` and `while` expressions - -error: expected expression, found `let` statement - --> $DIR/disallowed-positions.rs:102:9 - | -LL | if -let 0 = 0 {} - | ^^^^^^^^^ - | - = note: only supported directly in conditions of `if` and `while` expressions - -error: expected expression, found `let` statement - --> $DIR/disallowed-positions.rs:110:9 - | -LL | if (let 0 = 0)? {} - | ^^^^^^^^^ - | - = note: only supported directly in conditions of `if` and `while` expressions - -error: expected expression, found `let` statement - --> $DIR/disallowed-positions.rs:113:16 - | -LL | if true || let 0 = 0 {} - | ^^^^^^^^^ - | - = note: only supported directly in conditions of `if` and `while` expressions -note: `||` operators are not supported in let chain expressions - --> $DIR/disallowed-positions.rs:113:13 - | -LL | if true || let 0 = 0 {} - | ^^ - -error: expected expression, found `let` statement - --> $DIR/disallowed-positions.rs:115:17 - | -LL | if (true || let 0 = 0) {} - | ^^^^^^^^^ - | - = note: only supported directly in conditions of `if` and `while` expressions - -error: expected expression, found `let` statement - --> $DIR/disallowed-positions.rs:117:25 - | -LL | if true && (true || let 0 = 0) {} - | ^^^^^^^^^ - | - = note: only supported directly in conditions of `if` and `while` expressions - -error: expected expression, found `let` statement - --> $DIR/disallowed-positions.rs:119:25 - | -LL | if true || (true && let 0 = 0) {} - | ^^^^^^^^^ - | - = note: only supported directly in conditions of `if` and `while` expressions - -error: expected expression, found `let` statement - --> $DIR/disallowed-positions.rs:123:12 - | -LL | if x = let 0 = 0 {} - | ^^^ - | - = note: only supported directly in conditions of `if` and `while` expressions - -error: expected expression, found `let` statement - --> $DIR/disallowed-positions.rs:126:15 - | -LL | if true..(let 0 = 0) {} - | ^^^^^^^^^ - | - = note: only supported directly in conditions of `if` and `while` expressions - -error: expected expression, found `let` statement - --> $DIR/disallowed-positions.rs:129:11 - | -LL | if ..(let 0 = 0) {} - | ^^^^^^^^^ - | - = note: only supported directly in conditions of `if` and `while` expressions - -error: expected expression, found `let` statement - --> $DIR/disallowed-positions.rs:131:9 - | -LL | if (let 0 = 0).. {} - | ^^^^^^^^^ - | - = note: only supported directly in conditions of `if` and `while` expressions - -error: expected expression, found `let` statement - --> $DIR/disallowed-positions.rs:135:8 - | -LL | if let Range { start: _, end: _ } = true..true && false {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | - = note: only supported directly in conditions of `if` and `while` expressions - -error: expected expression, found `let` statement - --> $DIR/disallowed-positions.rs:138:8 - | -LL | if let Range { start: _, end: _ } = true..true || false {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | - = note: only supported directly in conditions of `if` and `while` expressions - -error: expected expression, found `let` statement - --> $DIR/disallowed-positions.rs:144:8 - | -LL | if let Range { start: F, end } = F..|| true {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | - = note: only supported directly in conditions of `if` and `while` expressions - -error: expected expression, found `let` statement - --> $DIR/disallowed-positions.rs:150:8 - | -LL | if let Range { start: true, end } = t..&&false {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | - = note: only supported directly in conditions of `if` and `while` expressions - -error: expected expression, found `let` statement - --> $DIR/disallowed-positions.rs:154:19 - | -LL | if let true = let true = true {} - | ^^^ - | - = note: only supported directly in conditions of `if` and `while` expressions - -error: expected expression, found `let` statement - --> $DIR/disallowed-positions.rs:160:12 - | -LL | while &let 0 = 0 {} - | ^^^^^^^^^ - | - = note: only supported directly in conditions of `if` and `while` expressions - -error: expected expression, found `let` statement - --> $DIR/disallowed-positions.rs:163:12 - | -LL | while !let 0 = 0 {} - | ^^^^^^^^^ - | - = note: only supported directly in conditions of `if` and `while` expressions - -error: expected expression, found `let` statement - --> $DIR/disallowed-positions.rs:165:12 - | -LL | while *let 0 = 0 {} - | ^^^^^^^^^ - | - = note: only supported directly in conditions of `if` and `while` expressions - -error: expected expression, found `let` statement - --> $DIR/disallowed-positions.rs:167:12 - | -LL | while -let 0 = 0 {} - | ^^^^^^^^^ - | - = note: only supported directly in conditions of `if` and `while` expressions - -error: expected expression, found `let` statement - --> $DIR/disallowed-positions.rs:175:12 - | -LL | while (let 0 = 0)? {} - | ^^^^^^^^^ - | - = note: only supported directly in conditions of `if` and `while` expressions - -error: expected expression, found `let` statement - --> $DIR/disallowed-positions.rs:178:19 - | -LL | while true || let 0 = 0 {} - | ^^^^^^^^^ - | - = note: only supported directly in conditions of `if` and `while` expressions -note: `||` operators are not supported in let chain expressions - --> $DIR/disallowed-positions.rs:178:16 - | -LL | while true || let 0 = 0 {} - | ^^ - -error: expected expression, found `let` statement - --> $DIR/disallowed-positions.rs:180:20 - | -LL | while (true || let 0 = 0) {} - | ^^^^^^^^^ - | - = note: only supported directly in conditions of `if` and `while` expressions - -error: expected expression, found `let` statement - --> $DIR/disallowed-positions.rs:182:28 - | -LL | while true && (true || let 0 = 0) {} - | ^^^^^^^^^ - | - = note: only supported directly in conditions of `if` and `while` expressions - -error: expected expression, found `let` statement - --> $DIR/disallowed-positions.rs:184:28 - | -LL | while true || (true && let 0 = 0) {} - | ^^^^^^^^^ - | - = note: only supported directly in conditions of `if` and `while` expressions - -error: expected expression, found `let` statement - --> $DIR/disallowed-positions.rs:188:15 - | -LL | while x = let 0 = 0 {} - | ^^^ - | - = note: only supported directly in conditions of `if` and `while` expressions - -error: expected expression, found `let` statement - --> $DIR/disallowed-positions.rs:191:18 - | -LL | while true..(let 0 = 0) {} - | ^^^^^^^^^ - | - = note: only supported directly in conditions of `if` and `while` expressions - -error: expected expression, found `let` statement - --> $DIR/disallowed-positions.rs:194:14 - | -LL | while ..(let 0 = 0) {} - | ^^^^^^^^^ - | - = note: only supported directly in conditions of `if` and `while` expressions - -error: expected expression, found `let` statement - --> $DIR/disallowed-positions.rs:196:12 - | -LL | while (let 0 = 0).. {} - | ^^^^^^^^^ - | - = note: only supported directly in conditions of `if` and `while` expressions - -error: expected expression, found `let` statement - --> $DIR/disallowed-positions.rs:200:11 - | -LL | while let Range { start: _, end: _ } = true..true && false {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | - = note: only supported directly in conditions of `if` and `while` expressions - -error: expected expression, found `let` statement - --> $DIR/disallowed-positions.rs:203:11 - | -LL | while let Range { start: _, end: _ } = true..true || false {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | - = note: only supported directly in conditions of `if` and `while` expressions - -error: expected expression, found `let` statement - --> $DIR/disallowed-positions.rs:209:11 - | -LL | while let Range { start: F, end } = F..|| true {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | - = note: only supported directly in conditions of `if` and `while` expressions - -error: expected expression, found `let` statement - --> $DIR/disallowed-positions.rs:215:11 - | -LL | while let Range { start: true, end } = t..&&false {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | - = note: only supported directly in conditions of `if` and `while` expressions - -error: expected expression, found `let` statement - --> $DIR/disallowed-positions.rs:219:22 - | -LL | while let true = let true = true {} - | ^^^ - | - = note: only supported directly in conditions of `if` and `while` expressions - -error: expected expression, found `let` statement - --> $DIR/disallowed-positions.rs:236:6 - | -LL | &let 0 = 0; - | ^^^ - | - = note: only supported directly in conditions of `if` and `while` expressions - -error: expected expression, found `let` statement - --> $DIR/disallowed-positions.rs:239:6 - | -LL | !let 0 = 0; - | ^^^ - | - = note: only supported directly in conditions of `if` and `while` expressions - -error: expected expression, found `let` statement - --> $DIR/disallowed-positions.rs:241:6 - | -LL | *let 0 = 0; - | ^^^ - | - = note: only supported directly in conditions of `if` and `while` expressions - -error: expected expression, found `let` statement - --> $DIR/disallowed-positions.rs:243:6 - | -LL | -let 0 = 0; - | ^^^ - | - = note: only supported directly in conditions of `if` and `while` expressions - -error: expected expression, found `let` statement - --> $DIR/disallowed-positions.rs:245:13 - | -LL | let _ = let _ = 3; - | ^^^ - | - = note: only supported directly in conditions of `if` and `while` expressions - -error: expected expression, found `let` statement - --> $DIR/disallowed-positions.rs:253:6 - | -LL | (let 0 = 0)?; - | ^^^ - | - = note: only supported directly in conditions of `if` and `while` expressions - -error: expected expression, found `let` statement - --> $DIR/disallowed-positions.rs:256:13 - | -LL | true || let 0 = 0; - | ^^^ - | - = note: only supported directly in conditions of `if` and `while` expressions - -error: expected expression, found `let` statement - --> $DIR/disallowed-positions.rs:258:14 - | -LL | (true || let 0 = 0); - | ^^^ - | - = note: only supported directly in conditions of `if` and `while` expressions - -error: expected expression, found `let` statement - --> $DIR/disallowed-positions.rs:260:22 - | -LL | true && (true || let 0 = 0); - | ^^^ - | - = note: only supported directly in conditions of `if` and `while` expressions - -error: expected expression, found `let` statement - --> $DIR/disallowed-positions.rs:264:9 - | -LL | x = let 0 = 0; - | ^^^ - | - = note: only supported directly in conditions of `if` and `while` expressions - -error: expected expression, found `let` statement - --> $DIR/disallowed-positions.rs:267:12 - | -LL | true..(let 0 = 0); - | ^^^ - | - = note: only supported directly in conditions of `if` and `while` expressions - -error: expected expression, found `let` statement - --> $DIR/disallowed-positions.rs:269:8 - | -LL | ..(let 0 = 0); - | ^^^ - | - = note: only supported directly in conditions of `if` and `while` expressions - -error: expected expression, found `let` statement - --> $DIR/disallowed-positions.rs:271:6 - | -LL | (let 0 = 0)..; - | ^^^ - | - = note: only supported directly in conditions of `if` and `while` expressions - -error: expected expression, found `let` statement - --> $DIR/disallowed-positions.rs:274:6 - | -LL | (let Range { start: _, end: _ } = true..true || false); - | ^^^ - | - = note: only supported directly in conditions of `if` and `while` expressions - -error: expected expression, found `let` statement - --> $DIR/disallowed-positions.rs:278:6 - | -LL | (let true = let true = true); - | ^^^ - | - = note: only supported directly in conditions of `if` and `while` expressions - -error: expected expression, found `let` statement - --> $DIR/disallowed-positions.rs:278:17 - | -LL | (let true = let true = true); - | ^^^ - | - = note: only supported directly in conditions of `if` and `while` expressions - -error: expected expression, found `let` statement - --> $DIR/disallowed-positions.rs:284:25 - | -LL | let x = true && let y = 1; - | ^^^ - | - = note: only supported directly in conditions of `if` and `while` expressions - -error: expected expression, found `let` statement - --> $DIR/disallowed-positions.rs:290:19 - | -LL | [1, 2, 3][let _ = ()] - | ^^^ - | - = note: only supported directly in conditions of `if` and `while` expressions - -error: expected expression, found `let` statement - --> $DIR/disallowed-positions.rs:295:6 - | -LL | &let 0 = 0 - | ^^^ - | - = note: only supported directly in conditions of `if` and `while` expressions - -error: expected expression, found `let` statement - --> $DIR/disallowed-positions.rs:306:17 - | -LL | true && let 1 = 1 - | ^^^ - | - = note: only supported directly in conditions of `if` and `while` expressions - -error: expected expression, found `let` statement - --> $DIR/disallowed-positions.rs:311:17 - | -LL | true && let 1 = 1 - | ^^^ - | - = note: only supported directly in conditions of `if` and `while` expressions - -error: expected expression, found `let` statement - --> $DIR/disallowed-positions.rs:316:17 - | -LL | true && let 1 = 1 - | ^^^ - | - = note: only supported directly in conditions of `if` and `while` expressions - -error: expected expression, found `let` statement - --> $DIR/disallowed-positions.rs:327:17 - | -LL | true && let 1 = 1 - | ^^^ - | - = note: only supported directly in conditions of `if` and `while` expressions - -error: expressions must be enclosed in braces to be used as const generic arguments - --> $DIR/disallowed-positions.rs:327:9 - | -LL | true && let 1 = 1 - | ^^^^^^^^^^^^^^^^^ - | -help: enclose the `const` expression in braces - | -LL | { true && let 1 = 1 } - | + + - -error: expected expression, found `let` statement - --> $DIR/disallowed-positions.rs:337:9 - | -LL | if (let Some(a) = opt && true) { - | ^^^^^^^^^^^^^^^^^ - | - = note: only supported directly in conditions of `if` and `while` expressions -note: `let`s wrapped in parentheses are not supported in a context with let chains - --> $DIR/disallowed-positions.rs:337:9 - | -LL | if (let Some(a) = opt && true) { - | ^^^^^^^^^^^^^^^^^^^^^^^^^ - -error: expected expression, found `let` statement - --> $DIR/disallowed-positions.rs:341:9 - | -LL | if (let Some(a) = opt) && true { - | ^^^^^^^^^^^^^^^^^ - | - = note: only supported directly in conditions of `if` and `while` expressions -note: `let`s wrapped in parentheses are not supported in a context with let chains - --> $DIR/disallowed-positions.rs:341:9 - | -LL | if (let Some(a) = opt) && true { - | ^^^^^^^^^^^^^^^^^ - -error: expected expression, found `let` statement - --> $DIR/disallowed-positions.rs:344:9 - | -LL | if (let Some(a) = opt) && (let Some(b) = a) { - | ^^^^^^^^^^^^^^^^^ - | - = note: only supported directly in conditions of `if` and `while` expressions -note: `let`s wrapped in parentheses are not supported in a context with let chains - --> $DIR/disallowed-positions.rs:344:9 - | -LL | if (let Some(a) = opt) && (let Some(b) = a) { - | ^^^^^^^^^^^^^^^^^ - -error: expected expression, found `let` statement - --> $DIR/disallowed-positions.rs:344:32 - | -LL | if (let Some(a) = opt) && (let Some(b) = a) { - | ^^^^^^^^^^^^^^^ - | - = note: only supported directly in conditions of `if` and `while` expressions -note: `let`s wrapped in parentheses are not supported in a context with let chains - --> $DIR/disallowed-positions.rs:344:32 - | -LL | if (let Some(a) = opt) && (let Some(b) = a) { - | ^^^^^^^^^^^^^^^ - -error: expected expression, found `let` statement - --> $DIR/disallowed-positions.rs:351:9 - | -LL | if (let Some(a) = opt && (let Some(b) = a)) && b == 1 { - | ^^^^^^^^^^^^^^^^^ - | - = note: only supported directly in conditions of `if` and `while` expressions -note: `let`s wrapped in parentheses are not supported in a context with let chains - --> $DIR/disallowed-positions.rs:351:9 - | -LL | if (let Some(a) = opt && (let Some(b) = a)) && b == 1 { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -error: expected expression, found `let` statement - --> $DIR/disallowed-positions.rs:351:31 - | -LL | if (let Some(a) = opt && (let Some(b) = a)) && b == 1 { - | ^^^^^^^^^^^^^^^ - | - = note: only supported directly in conditions of `if` and `while` expressions -note: `let`s wrapped in parentheses are not supported in a context with let chains - --> $DIR/disallowed-positions.rs:351:31 - | -LL | if (let Some(a) = opt && (let Some(b) = a)) && b == 1 { - | ^^^^^^^^^^^^^^^ - -error: expected expression, found `let` statement - --> $DIR/disallowed-positions.rs:355:9 - | -LL | if (let Some(a) = opt && (let Some(b) = a)) && true { - | ^^^^^^^^^^^^^^^^^ - | - = note: only supported directly in conditions of `if` and `while` expressions -note: `let`s wrapped in parentheses are not supported in a context with let chains - --> $DIR/disallowed-positions.rs:355:9 - | -LL | if (let Some(a) = opt && (let Some(b) = a)) && true { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -error: expected expression, found `let` statement - --> $DIR/disallowed-positions.rs:355:31 - | -LL | if (let Some(a) = opt && (let Some(b) = a)) && true { - | ^^^^^^^^^^^^^^^ - | - = note: only supported directly in conditions of `if` and `while` expressions -note: `let`s wrapped in parentheses are not supported in a context with let chains - --> $DIR/disallowed-positions.rs:355:31 - | -LL | if (let Some(a) = opt && (let Some(b) = a)) && true { - | ^^^^^^^^^^^^^^^ - -error: expected expression, found `let` statement - --> $DIR/disallowed-positions.rs:359:9 - | -LL | if (let Some(a) = opt && (true)) && true { - | ^^^^^^^^^^^^^^^^^ - | - = note: only supported directly in conditions of `if` and `while` expressions -note: `let`s wrapped in parentheses are not supported in a context with let chains - --> $DIR/disallowed-positions.rs:359:9 - | -LL | if (let Some(a) = opt && (true)) && true { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -error: expected expression, found `let` statement - --> $DIR/disallowed-positions.rs:375:22 - | -LL | let x = (true && let y = 1); - | ^^^ - | - = note: only supported directly in conditions of `if` and `while` expressions - -error: expected expression, found `let` statement - --> $DIR/disallowed-positions.rs:380:20 - | -LL | ([1, 2, 3][let _ = ()]) - | ^^^ - | - = note: only supported directly in conditions of `if` and `while` expressions - -error: expected expression, found `let` statement - --> $DIR/disallowed-positions.rs:87:16 - | -LL | use_expr!((let 0 = 1 && 0 == 0)); - | ^^^ - | - = note: only supported directly in conditions of `if` and `while` expressions - -error: expected expression, found `let` statement - --> $DIR/disallowed-positions.rs:89:16 - | -LL | use_expr!((let 0 = 1)); - | ^^^ - | - = note: only supported directly in conditions of `if` and `while` expressions - -error[E0658]: `let` expressions in this position are unstable - --> $DIR/disallowed-positions.rs:47:8 - | -LL | if let 0 = 1 && let 1 = 2 && (let 2 = 3 && let 3 = 4 && let 4 = 5) {} - | ^^^^^^^^^ - | - = note: see issue #53667 for more information - = help: add `#![feature(let_chains)]` 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]: `let` expressions in this position are unstable - --> $DIR/disallowed-positions.rs:47:21 - | -LL | if let 0 = 1 && let 1 = 2 && (let 2 = 3 && let 3 = 4 && let 4 = 5) {} - | ^^^^^^^^^ - | - = note: see issue #53667 for more information - = help: add `#![feature(let_chains)]` 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]: `let` expressions in this position are unstable - --> $DIR/disallowed-positions.rs:72:11 - | -LL | while let 0 = 1 && let 1 = 2 && (let 2 = 3 && let 3 = 4 && let 4 = 5) {} - | ^^^^^^^^^ - | - = note: see issue #53667 for more information - = help: add `#![feature(let_chains)]` 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]: `let` expressions in this position are unstable - --> $DIR/disallowed-positions.rs:72:24 - | -LL | while let 0 = 1 && let 1 = 2 && (let 2 = 3 && let 3 = 4 && let 4 = 5) {} - | ^^^^^^^^^ - | - = note: see issue #53667 for more information - = help: add `#![feature(let_chains)]` 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]: `let` expressions in this position are unstable - --> $DIR/disallowed-positions.rs:348:8 - | -LL | if let Some(a) = opt && (true && true) { - | ^^^^^^^^^^^^^^^^^ - | - = note: see issue #53667 for more information - = help: add `#![feature(let_chains)]` 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]: `let` expressions in this position are unstable - --> $DIR/disallowed-positions.rs:363:28 - | -LL | if (true && (true)) && let Some(a) = opt { - | ^^^^^^^^^^^^^^^^^ - | - = note: see issue #53667 for more information - = help: add `#![feature(let_chains)]` 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]: `let` expressions in this position are unstable - --> $DIR/disallowed-positions.rs:365:18 - | -LL | if (true) && let Some(a) = opt { - | ^^^^^^^^^^^^^^^^^ - | - = note: see issue #53667 for more information - = help: add `#![feature(let_chains)]` 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]: `let` expressions in this position are unstable - --> $DIR/disallowed-positions.rs:367:16 - | -LL | if true && let Some(a) = opt { - | ^^^^^^^^^^^^^^^^^ - | - = note: see issue #53667 for more information - = help: add `#![feature(let_chains)]` 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]: `let` expressions in this position are unstable - --> $DIR/disallowed-positions.rs:371:8 - | -LL | if let true = (true && fun()) && (true) { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ - | - = note: see issue #53667 for more information - = help: add `#![feature(let_chains)]` 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[E0308]: mismatched types - --> $DIR/disallowed-positions.rs:126:8 - | -LL | if true..(let 0 = 0) {} - | ^^^^^^^^^^^^^^^^^ expected `bool`, found `Range` - | - = note: expected type `bool` - found struct `std::ops::Range` - -error[E0308]: mismatched types - --> $DIR/disallowed-positions.rs:135:12 - | -LL | if let Range { start: _, end: _ } = true..true && false {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ ---- this expression has type `bool` - | | - | expected `bool`, found `Range<_>` - | - = note: expected type `bool` - found struct `std::ops::Range<_>` - -error[E0308]: mismatched types - --> $DIR/disallowed-positions.rs:138:12 - | -LL | if let Range { start: _, end: _ } = true..true || false {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ ---- this expression has type `bool` - | | - | expected `bool`, found `Range<_>` - | - = note: expected type `bool` - found struct `std::ops::Range<_>` - -error[E0308]: mismatched types - --> $DIR/disallowed-positions.rs:144:12 - | -LL | if let Range { start: F, end } = F..|| true {} - | ^^^^^^^^^^^^^^^^^^^^^^^ - this expression has type `fn() -> bool` - | | - | expected fn pointer, found `Range<_>` - | - = note: expected fn pointer `fn() -> bool` - found struct `std::ops::Range<_>` - -error[E0308]: mismatched types - --> $DIR/disallowed-positions.rs:150:12 - | -LL | if let Range { start: true, end } = t..&&false {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ - this expression has type `&&bool` - | | - | expected `bool`, found `Range<_>` - | - = note: expected type `bool` - found struct `std::ops::Range<_>` - -error[E0277]: the `?` operator can only be applied to values that implement `Try` - --> $DIR/disallowed-positions.rs:106:20 - | -LL | if let 0 = 0? {} - | ^^ the `?` operator cannot be applied to type `{integer}` - | - = help: the trait `Try` is not implemented for `{integer}` - -error[E0308]: mismatched types - --> $DIR/disallowed-positions.rs:191:11 - | -LL | while true..(let 0 = 0) {} - | ^^^^^^^^^^^^^^^^^ expected `bool`, found `Range` - | - = note: expected type `bool` - found struct `std::ops::Range` - -error[E0308]: mismatched types - --> $DIR/disallowed-positions.rs:200:15 - | -LL | while let Range { start: _, end: _ } = true..true && false {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ ---- this expression has type `bool` - | | - | expected `bool`, found `Range<_>` - | - = note: expected type `bool` - found struct `std::ops::Range<_>` - -error[E0308]: mismatched types - --> $DIR/disallowed-positions.rs:203:15 - | -LL | while let Range { start: _, end: _ } = true..true || false {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ ---- this expression has type `bool` - | | - | expected `bool`, found `Range<_>` - | - = note: expected type `bool` - found struct `std::ops::Range<_>` - -error[E0308]: mismatched types - --> $DIR/disallowed-positions.rs:209:15 - | -LL | while let Range { start: F, end } = F..|| true {} - | ^^^^^^^^^^^^^^^^^^^^^^^ - this expression has type `fn() -> bool` - | | - | expected fn pointer, found `Range<_>` - | - = note: expected fn pointer `fn() -> bool` - found struct `std::ops::Range<_>` - -error[E0308]: mismatched types - --> $DIR/disallowed-positions.rs:215:15 - | -LL | while let Range { start: true, end } = t..&&false {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ - this expression has type `&&bool` - | | - | expected `bool`, found `Range<_>` - | - = note: expected type `bool` - found struct `std::ops::Range<_>` - -error[E0277]: the `?` operator can only be applied to values that implement `Try` - --> $DIR/disallowed-positions.rs:171:23 - | -LL | while let 0 = 0? {} - | ^^ the `?` operator cannot be applied to type `{integer}` - | - = help: the trait `Try` is not implemented for `{integer}` - -error[E0308]: mismatched types - --> $DIR/disallowed-positions.rs:274:10 - | -LL | (let Range { start: _, end: _ } = true..true || false); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ ---- this expression has type `bool` - | | - | expected `bool`, found `Range<_>` - | - = note: expected type `bool` - found struct `std::ops::Range<_>` - -error[E0277]: the `?` operator can only be applied to values that implement `Try` - --> $DIR/disallowed-positions.rs:249:17 - | -LL | let 0 = 0?; - | ^^ the `?` operator cannot be applied to type `{integer}` - | - = help: the trait `Try` is not implemented for `{integer}` - -error: aborting due to 114 previous errors - -Some errors have detailed explanations: E0277, E0308, E0658. -For more information about an error, try `rustc --explain E0277`. diff --git a/tests/ui/rmeta/emit-artifact-notifications.polonius.stderr b/tests/ui/rmeta/emit-artifact-notifications.polonius.stderr deleted file mode 100644 index 255c7b370f9f..000000000000 --- a/tests/ui/rmeta/emit-artifact-notifications.polonius.stderr +++ /dev/null @@ -1 +0,0 @@ -{"artifact":"$TEST_BUILD_DIR/rmeta/emit-artifact-notifications.polonius/libemit_artifact_notifications.rmeta","emit":"metadata"} diff --git a/tests/ui/rust-2024/safe-outside-extern.gated.stderr b/tests/ui/rust-2024/safe-outside-extern.gated.stderr deleted file mode 100644 index e0b218281f36..000000000000 --- a/tests/ui/rust-2024/safe-outside-extern.gated.stderr +++ /dev/null @@ -1,38 +0,0 @@ -error: items outside of `unsafe extern { }` cannot be declared with `safe` safety qualifier - --> $DIR/safe-outside-extern.rs:4:1 - | -LL | safe fn foo() {} - | ^^^^^^^^^^^^^^^^ - -error: items outside of `unsafe extern { }` cannot be declared with `safe` safety qualifier - --> $DIR/safe-outside-extern.rs:8:1 - | -LL | safe static FOO: i32 = 1; - | ^^^^^^^^^^^^^^^^^^^^^^^^^ - -error: items outside of `unsafe extern { }` cannot be declared with `safe` safety qualifier - --> $DIR/safe-outside-extern.rs:13:5 - | -LL | safe fn foo(); - | ^^^^^^^^^^^^^^ - -error: items outside of `unsafe extern { }` cannot be declared with `safe` safety qualifier - --> $DIR/safe-outside-extern.rs:19:5 - | -LL | safe fn foo() {} - | ^^^^^^^^^^^^^^^^ - -error: function pointers cannot be declared with `safe` safety qualifier - --> $DIR/safe-outside-extern.rs:24:14 - | -LL | type FnPtr = safe fn(i32, i32) -> i32; - | ^^^^^^^^^^^^^^^^^^^^^^^^ - -error: static items cannot be declared with `unsafe` safety qualifier outside of `extern` block - --> $DIR/safe-outside-extern.rs:28:1 - | -LL | unsafe static LOL: u8 = 0; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ - -error: aborting due to 6 previous errors - diff --git a/tests/ui/rust-2024/safe-outside-extern.ungated.stderr b/tests/ui/rust-2024/safe-outside-extern.ungated.stderr deleted file mode 100644 index 98a4c0eab921..000000000000 --- a/tests/ui/rust-2024/safe-outside-extern.ungated.stderr +++ /dev/null @@ -1,89 +0,0 @@ -error: items outside of `unsafe extern { }` cannot be declared with `safe` safety qualifier - --> $DIR/safe-outside-extern.rs:4:1 - | -LL | safe fn foo() {} - | ^^^^^^^^^^^^^^^^ - -error: items outside of `unsafe extern { }` cannot be declared with `safe` safety qualifier - --> $DIR/safe-outside-extern.rs:8:1 - | -LL | safe static FOO: i32 = 1; - | ^^^^^^^^^^^^^^^^^^^^^^^^^ - -error: items outside of `unsafe extern { }` cannot be declared with `safe` safety qualifier - --> $DIR/safe-outside-extern.rs:13:5 - | -LL | safe fn foo(); - | ^^^^^^^^^^^^^^ - -error: items outside of `unsafe extern { }` cannot be declared with `safe` safety qualifier - --> $DIR/safe-outside-extern.rs:19:5 - | -LL | safe fn foo() {} - | ^^^^^^^^^^^^^^^^ - -error: function pointers cannot be declared with `safe` safety qualifier - --> $DIR/safe-outside-extern.rs:24:14 - | -LL | type FnPtr = safe fn(i32, i32) -> i32; - | ^^^^^^^^^^^^^^^^^^^^^^^^ - -error: static items cannot be declared with `unsafe` safety qualifier outside of `extern` block - --> $DIR/safe-outside-extern.rs:28:1 - | -LL | unsafe static LOL: u8 = 0; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ - -error[E0658]: `unsafe extern {}` blocks and `safe` keyword are experimental - --> $DIR/safe-outside-extern.rs:4:1 - | -LL | safe fn foo() {} - | ^^^^ - | - = note: see issue #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[E0658]: `unsafe extern {}` blocks and `safe` keyword are experimental - --> $DIR/safe-outside-extern.rs:8:1 - | -LL | safe static FOO: i32 = 1; - | ^^^^ - | - = note: see issue #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[E0658]: `unsafe extern {}` blocks and `safe` keyword are experimental - --> $DIR/safe-outside-extern.rs:13:5 - | -LL | safe fn foo(); - | ^^^^ - | - = note: see issue #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[E0658]: `unsafe extern {}` blocks and `safe` keyword are experimental - --> $DIR/safe-outside-extern.rs:19:5 - | -LL | safe fn foo() {} - | ^^^^ - | - = note: see issue #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[E0658]: `unsafe extern {}` blocks and `safe` keyword are experimental - --> $DIR/safe-outside-extern.rs:24:14 - | -LL | type FnPtr = safe fn(i32, i32) -> i32; - | ^^^^ - | - = note: see issue #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 11 previous errors - -For more information about this error, try `rustc --explain E0658`. diff --git a/tests/ui/rust-2024/unsafe-extern-blocks/safe-impl-trait.ungated.stderr b/tests/ui/rust-2024/unsafe-extern-blocks/safe-impl-trait.ungated.stderr deleted file mode 100644 index 80e7a45f57e7..000000000000 --- a/tests/ui/rust-2024/unsafe-extern-blocks/safe-impl-trait.ungated.stderr +++ /dev/null @@ -1,8 +0,0 @@ -error: expected one of `!` or `::`, found keyword `impl` - --> $DIR/safe-impl-trait.rs:5:6 - | -LL | safe impl Bar for () { } - | ^^^^ expected one of `!` or `::` - -error: aborting due to 1 previous error - diff --git a/tests/ui/rust-2024/unsafe-extern-blocks/safe-trait.gated.stderr b/tests/ui/rust-2024/unsafe-extern-blocks/safe-trait.gated.stderr deleted file mode 100644 index de84037f28c5..000000000000 --- a/tests/ui/rust-2024/unsafe-extern-blocks/safe-trait.gated.stderr +++ /dev/null @@ -1,8 +0,0 @@ -error: expected one of `!` or `::`, found keyword `trait` - --> $DIR/safe-trait.rs:4:6 - | -LL | safe trait Foo {} - | ^^^^^ expected one of `!` or `::` - -error: aborting due to 1 previous error - diff --git a/tests/ui/rust-2024/unsafe-extern-blocks/safe-trait.ungated.stderr b/tests/ui/rust-2024/unsafe-extern-blocks/safe-trait.ungated.stderr deleted file mode 100644 index de84037f28c5..000000000000 --- a/tests/ui/rust-2024/unsafe-extern-blocks/safe-trait.ungated.stderr +++ /dev/null @@ -1,8 +0,0 @@ -error: expected one of `!` or `::`, found keyword `trait` - --> $DIR/safe-trait.rs:4:6 - | -LL | safe trait Foo {} - | ^^^^^ expected one of `!` or `::` - -error: aborting due to 1 previous error - diff --git a/tests/ui/specialization/specialization-default-items-drop-coherence.coherence.stderr b/tests/ui/specialization/specialization-default-items-drop-coherence.coherence.stderr deleted file mode 100644 index e9498a003179..000000000000 --- a/tests/ui/specialization/specialization-default-items-drop-coherence.coherence.stderr +++ /dev/null @@ -1,12 +0,0 @@ -error[E0119]: conflicting implementations of trait `Overlap` for type `u32` - --> $DIR/specialization-default-items-drop-coherence.rs:29:1 - | -LL | impl Overlap for u32 { - | -------------------- first implementation here -... -LL | impl Overlap for ::Id { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `u32` - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0119`. diff --git a/tests/ui/specialization/specialization-overlap-projection.current.stderr b/tests/ui/specialization/specialization-overlap-projection.current.stderr deleted file mode 100644 index 4e77cb17fbb0..000000000000 --- a/tests/ui/specialization/specialization-overlap-projection.current.stderr +++ /dev/null @@ -1,30 +0,0 @@ -warning: the feature `specialization` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/specialization-overlap-projection.rs:4:12 - | -LL | #![feature(specialization)] - | ^^^^^^^^^^^^^^ - | - = note: see issue #31844 for more information - = help: consider using `min_specialization` instead, which is more stable and complete - = note: `#[warn(incomplete_features)]` on by default - -error[E0119]: conflicting implementations of trait `Foo` for type `u32` - --> $DIR/specialization-overlap-projection.rs:19:1 - | -LL | impl Foo for u32 {} - | ---------------- first implementation here -LL | impl Foo for ::Output {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `u32` - -error[E0119]: conflicting implementations of trait `Foo` for type `u32` - --> $DIR/specialization-overlap-projection.rs:21:1 - | -LL | impl Foo for u32 {} - | ---------------- first implementation here -... -LL | impl Foo for ::Output {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `u32` - -error: aborting due to 2 previous errors; 1 warning emitted - -For more information about this error, try `rustc --explain E0119`. diff --git a/tests/ui/specialization/specialization-overlap-projection.next.stderr b/tests/ui/specialization/specialization-overlap-projection.next.stderr deleted file mode 100644 index 4e77cb17fbb0..000000000000 --- a/tests/ui/specialization/specialization-overlap-projection.next.stderr +++ /dev/null @@ -1,30 +0,0 @@ -warning: the feature `specialization` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/specialization-overlap-projection.rs:4:12 - | -LL | #![feature(specialization)] - | ^^^^^^^^^^^^^^ - | - = note: see issue #31844 for more information - = help: consider using `min_specialization` instead, which is more stable and complete - = note: `#[warn(incomplete_features)]` on by default - -error[E0119]: conflicting implementations of trait `Foo` for type `u32` - --> $DIR/specialization-overlap-projection.rs:19:1 - | -LL | impl Foo for u32 {} - | ---------------- first implementation here -LL | impl Foo for ::Output {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `u32` - -error[E0119]: conflicting implementations of trait `Foo` for type `u32` - --> $DIR/specialization-overlap-projection.rs:21:1 - | -LL | impl Foo for u32 {} - | ---------------- first implementation here -... -LL | impl Foo for ::Output {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `u32` - -error: aborting due to 2 previous errors; 1 warning emitted - -For more information about this error, try `rustc --explain E0119`. diff --git a/tests/ui/traits/next-solver/coherence/issue-102048.next.stderr b/tests/ui/traits/next-solver/coherence/issue-102048.next.stderr deleted file mode 100644 index 39fde307f23f..000000000000 --- a/tests/ui/traits/next-solver/coherence/issue-102048.next.stderr +++ /dev/null @@ -1,16 +0,0 @@ -error[E0119]: conflicting implementations of trait `Trait fn(<_ as WithAssoc1<'a>>::Assoc, <_ as WithAssoc2<'a>>::Assoc)>` for type `(_, _)` - --> $DIR/issue-102048.rs:44:1 - | -LL | / impl Trait fn(>::Assoc, >::Assoc)> for (T, U) -LL | | where -LL | | T: for<'a> WithAssoc1<'a> + for<'a> WithAssoc2<'a, Assoc = i32>, -LL | | U: for<'a> WithAssoc2<'a>, - | |______________________________- first implementation here -... -LL | / impl Trait fn(>::Assoc, u32)> for (T, U) where -LL | | U: for<'a> WithAssoc1<'a> - | |_____________________________^ conflicting implementation for `(_, _)` - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0119`. diff --git a/tests/ui/traits/trait-upcasting/type-checking-test-3.polonius.stderr b/tests/ui/traits/trait-upcasting/type-checking-test-3.polonius.stderr deleted file mode 100644 index e6cb6a753998..000000000000 --- a/tests/ui/traits/trait-upcasting/type-checking-test-3.polonius.stderr +++ /dev/null @@ -1,18 +0,0 @@ -error: lifetime may not live long enough - --> $DIR/type-checking-test-3.rs:11:13 - | -LL | fn test_wrong1<'a>(x: &dyn Foo<'static>, y: &'a u32) { - | -- lifetime `'a` defined here -LL | let _ = x as &dyn Bar<'a>; // Error - | ^^^^^^^^^^^^^^^^^ type annotation requires that `'a` must outlive `'static` - -error: lifetime may not live long enough - --> $DIR/type-checking-test-3.rs:16:13 - | -LL | fn test_wrong2<'a>(x: &dyn Foo<'a>) { - | -- lifetime `'a` defined here -LL | let _ = x as &dyn Bar<'static>; // Error - | ^^^^^^^^^^^^^^^^^^^^^^ type annotation requires that `'a` must outlive `'static` - -error: aborting due to 2 previous errors - diff --git a/tests/ui/traits/trait-upcasting/type-checking-test-4.polonius.stderr b/tests/ui/traits/trait-upcasting/type-checking-test-4.polonius.stderr deleted file mode 100644 index 8d506e5807ec..000000000000 --- a/tests/ui/traits/trait-upcasting/type-checking-test-4.polonius.stderr +++ /dev/null @@ -1,52 +0,0 @@ -error: lifetime may not live long enough - --> $DIR/type-checking-test-4.rs:15:13 - | -LL | fn test_wrong1<'a>(x: &dyn Foo<'static>, y: &'a u32) { - | -- lifetime `'a` defined here -LL | let _ = x as &dyn Bar<'static, 'a>; // Error - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ type annotation requires that `'a` must outlive `'static` - -error: lifetime may not live long enough - --> $DIR/type-checking-test-4.rs:20:13 - | -LL | fn test_wrong2<'a>(x: &dyn Foo<'static>, y: &'a u32) { - | -- lifetime `'a` defined here -LL | let _ = x as &dyn Bar<'a, 'static>; // Error - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ type annotation requires that `'a` must outlive `'static` - -error: lifetime may not live long enough - --> $DIR/type-checking-test-4.rs:26:5 - | -LL | fn test_wrong3<'a>(x: &dyn Foo<'a>) -> Option<&'static u32> { - | -- lifetime `'a` defined here -LL | let y = x as &dyn Bar<'_, '_>; -LL | y.get_b() // ERROR - | ^^^^^^^^^ returning this value requires that `'a` must outlive `'static` - -error: lifetime may not live long enough - --> $DIR/type-checking-test-4.rs:31:5 - | -LL | fn test_wrong4<'a>(x: &dyn Foo<'a>) -> Option<&'static u32> { - | -- lifetime `'a` defined here -LL | <_ as Bar>::get_b(x) // ERROR - | ^^^^^^^^^^^^^^^^^^^^ returning this value requires that `'a` must outlive `'static` - -error: lifetime may not live long enough - --> $DIR/type-checking-test-4.rs:36:5 - | -LL | fn test_wrong5<'a>(x: &dyn Foo<'a>) -> Option<&'static u32> { - | -- lifetime `'a` defined here -LL | <_ as Bar<'_, '_>>::get_b(x) // ERROR - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ returning this value requires that `'a` must outlive `'static` - -error: lifetime may not live long enough - --> $DIR/type-checking-test-4.rs:44:5 - | -LL | fn test_wrong6<'a>(x: &dyn Foo<'a>) -> Option<&'static u32> { - | -- lifetime `'a` defined here -... -LL | z.get_b() // ERROR - | ^^^^^^^^^ returning this value requires that `'a` must outlive `'static` - -error: aborting due to 6 previous errors - diff --git a/tests/ui/treat-err-as-bug/panic-causes-oom-112708.stderr b/tests/ui/treat-err-as-bug/panic-causes-oom-112708.stderr deleted file mode 100644 index 2d49071ac49c..000000000000 --- a/tests/ui/treat-err-as-bug/panic-causes-oom-112708.stderr +++ /dev/null @@ -1,32 +0,0 @@ -error: denote infinite loops with `loop { ... }` - --> $DIR/panic-causes-oom-112708.rs:13:5 - | -LL | while true {} - | ^^^^^^^^^^ help: use `loop` - | -note: the lint level is defined here - --> $DIR/panic-causes-oom-112708.rs:12:12 - | -LL | #[deny(while_true)] - | ^^^^^^^^^^ - - -query stack during panic: -#0 [early_lint_checks] perform lints prior to macro expansion -#1 [hir_crate] getting the crate HIR -end of query stack - -error: the compiler unexpectedly panicked. this is a bug. - -query stack during panic: -#0 [early_lint_checks] perform lints prior to macro expansion -#1 [hir_crate] getting the crate HIR -end of query stack - -error: the compiler unexpectedly panicked. this is a bug. - -query stack during panic: -#0 [early_lint_checks] perform lints prior to macro expansion -#1 [hir_crate] getting the crate HIR -end of query stack -thread caused non-unwinding panic. aborting. diff --git a/tests/ui/type-alias-impl-trait/wf-nested.fail.stderr b/tests/ui/type-alias-impl-trait/wf-nested.fail.stderr deleted file mode 100644 index 79b726f83dde..000000000000 --- a/tests/ui/type-alias-impl-trait/wf-nested.fail.stderr +++ /dev/null @@ -1,17 +0,0 @@ -error[E0310]: the parameter type `T` may not live long enough - --> $DIR/wf-nested.rs:64:38 - | -LL | fn define() -> OuterOpaque {} - | ^^ - | | - | the parameter type `T` must be valid for the static lifetime... - | ...so that the type `T` will meet its required lifetime bounds - | -help: consider adding an explicit lifetime bound - | -LL | fn define() -> OuterOpaque {} - | +++++++++ - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0310`. diff --git a/tests/ui/type-alias-impl-trait/wf-nested.pass.stderr b/tests/ui/type-alias-impl-trait/wf-nested.pass.stderr deleted file mode 100644 index b61b69d8e407..000000000000 --- a/tests/ui/type-alias-impl-trait/wf-nested.pass.stderr +++ /dev/null @@ -1,31 +0,0 @@ -error[E0310]: the parameter type `T` may not live long enough - --> $DIR/wf-nested.rs:34:38 - | -LL | fn define() -> OuterOpaque {} - | ^^ - | | - | the parameter type `T` must be valid for the static lifetime... - | ...so that the type `T` will meet its required lifetime bounds - | -help: consider adding an explicit lifetime bound - | -LL | fn define() -> OuterOpaque {} - | +++++++++ - -error[E0310]: the parameter type `T` may not live long enough - --> $DIR/wf-nested.rs:37:69 - | -LL | fn define_rpit() -> impl Trait<&'static T, Out = impl Sized> {} - | ^^ - | | - | the parameter type `T` must be valid for the static lifetime... - | ...so that the type `T` will meet its required lifetime bounds - | -help: consider adding an explicit lifetime bound - | -LL | fn define_rpit() -> impl Trait<&'static T, Out = impl Sized> {} - | +++++++++ - -error: aborting due to 2 previous errors - -For more information about this error, try `rustc --explain E0310`. diff --git a/tests/ui/type-alias-impl-trait/wf-nested.pass_sound.stderr b/tests/ui/type-alias-impl-trait/wf-nested.pass_sound.stderr deleted file mode 100644 index dbd3a1394f89..000000000000 --- a/tests/ui/type-alias-impl-trait/wf-nested.pass_sound.stderr +++ /dev/null @@ -1,46 +0,0 @@ -error[E0310]: the parameter type `T` may not live long enough - --> $DIR/wf-nested.rs:46:38 - | -LL | fn define() -> OuterOpaque {} - | ^^ - | | - | the parameter type `T` must be valid for the static lifetime... - | ...so that the type `T` will meet its required lifetime bounds - | -help: consider adding an explicit lifetime bound - | -LL | fn define() -> OuterOpaque {} - | +++++++++ - -error[E0310]: the parameter type `T` may not live long enough - --> $DIR/wf-nested.rs:51:17 - | -LL | let _ = outer.get(); - | ^^^^^^^^^^^ - | | - | the parameter type `T` must be valid for the static lifetime... - | ...so that the type `T` will meet its required lifetime bounds - | -help: consider adding an explicit lifetime bound - | -LL | fn test() { - | +++++++++ - -error[E0310]: the parameter type `T` may not live long enough - --> $DIR/wf-nested.rs:51:17 - | -LL | let _ = outer.get(); - | ^^^^^^^^^^^ - | | - | the parameter type `T` must be valid for the static lifetime... - | ...so that the type `T` will meet its required lifetime bounds - | - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` -help: consider adding an explicit lifetime bound - | -LL | fn test() { - | +++++++++ - -error: aborting due to 3 previous errors - -For more information about this error, try `rustc --explain E0310`. diff --git a/tests/ui/type/pattern_types/derives.noimpl.stderr b/tests/ui/type/pattern_types/derives.noimpl.stderr deleted file mode 100644 index 9450e5753446..000000000000 --- a/tests/ui/type/pattern_types/derives.noimpl.stderr +++ /dev/null @@ -1,14 +0,0 @@ -error[E0369]: binary operation `==` cannot be applied to type `(i32) is 0..=999999999` - --> $DIR/derives.rs:14:20 - | -LL | #[derive(Clone, Copy, PartialEq)] - | --------- in this derive macro expansion -LL | #[repr(transparent)] -LL | struct Nanoseconds(NanoI32); - | ^^^^^^^ - | - = note: this error originates in the derive macro `PartialEq` (in Nightly builds, run with -Z macro-backtrace for more info) - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0369`. diff --git a/tests/ui/type_length_limit.polonius.stderr b/tests/ui/type_length_limit.polonius.stderr deleted file mode 100644 index bc09f1591832..000000000000 --- a/tests/ui/type_length_limit.polonius.stderr +++ /dev/null @@ -1,11 +0,0 @@ -error: reached the type-length limit while instantiating `std::mem::drop::>` - --> $SRC_DIR/core/src/mem/mod.rs:LL:COL - | -LL | pub fn drop(_x: T) {} - | ^^^^^^^^^^^^^^^^^^^^^ - | - = note: the full type name has been written to '$TEST_BUILD_DIR/type_length_limit.polonius/type_length_limit.long-type.txt' - = help: consider adding a `#![type_length_limit="8"]` attribute to your crate - -error: aborting due to 1 previous error - diff --git a/tests/ui/uninhabited/uninhabited-irrefutable.min_exhaustive_patterns.stderr b/tests/ui/uninhabited/uninhabited-irrefutable.min_exhaustive_patterns.stderr deleted file mode 100644 index 67527ce1ac45..000000000000 --- a/tests/ui/uninhabited/uninhabited-irrefutable.min_exhaustive_patterns.stderr +++ /dev/null @@ -1,26 +0,0 @@ -error[E0005]: refutable pattern in local binding - --> $DIR/uninhabited-irrefutable.rs:31:9 - | -LL | let Foo::D(_y, _z) = x; - | ^^^^^^^^^^^^^^ pattern `Foo::A(_)` not covered - | - = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant - = note: for more information, visit https://doc.rust-lang.org/book/ch19-02-refutability.html -note: `Foo` defined here - --> $DIR/uninhabited-irrefutable.rs:20:6 - | -LL | enum Foo { - | ^^^ -LL | -LL | A(foo::SecretlyEmpty), - | - not covered - = note: pattern `Foo::A(_)` is currently uninhabited, but this variant contains private fields which may become inhabited in the future - = note: the matched value is of type `Foo` -help: you might want to use `let else` to handle the variant that isn't matched - | -LL | let Foo::D(_y, _z) = x else { todo!() }; - | ++++++++++++++++ - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0005`. From c38951b28064f09ab73901b1de244654e1520072 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Le=C3=B3n=20Orell=20Valerian=20Liehr?= Date: Mon, 27 Jan 2025 00:29:25 +0100 Subject: [PATCH 74/81] Make a previously unreachable UI test reachable --- src/tools/tidy/src/issues.txt | 1 - tests/ui/issues/auxiliary/issue-111011.stderr | 34 --------------- ...dont-suggest-boxing-async-closure-body.rs} | 4 +- ...t-suggest-boxing-async-closure-body.stderr | 41 +++++++++++++++++++ 4 files changed, 44 insertions(+), 36 deletions(-) delete mode 100644 tests/ui/issues/auxiliary/issue-111011.stderr rename tests/ui/{issues/auxiliary/issue-111011.rs => suggestions/dont-suggest-boxing-async-closure-body.rs} (53%) create mode 100644 tests/ui/suggestions/dont-suggest-boxing-async-closure-body.stderr diff --git a/src/tools/tidy/src/issues.txt b/src/tools/tidy/src/issues.txt index 5865664fc894..839d23fb9a78 100644 --- a/src/tools/tidy/src/issues.txt +++ b/src/tools/tidy/src/issues.txt @@ -1385,7 +1385,6 @@ ui/issue-18502.rs ui/issue-24106.rs ui/issue-76387-llvm-miscompile.rs ui/issues-71798.rs -ui/issues/auxiliary/issue-111011.rs ui/issues/auxiliary/issue-11224.rs ui/issues/auxiliary/issue-11508.rs ui/issues/auxiliary/issue-11529.rs diff --git a/tests/ui/issues/auxiliary/issue-111011.stderr b/tests/ui/issues/auxiliary/issue-111011.stderr deleted file mode 100644 index c0b48c5842f4..000000000000 --- a/tests/ui/issues/auxiliary/issue-111011.stderr +++ /dev/null @@ -1,34 +0,0 @@ -error[E0308]: mismatched types - --> $DIR/issue-111011.rs:10:23 - | -LL | foo(async move || {}); - | ^^ expected `Box<_>`, found `async` closure body - | - = note: expected struct `Box<_>` - found `async` closure body `[async closure body@$DIR/issue-111011.rs:10:23: 10:25]` - = note: for more on the distinction between the stack and the heap, read https://doc.rust-lang.org/book/ch15-01-box.html, https://doc.rust-lang.org/rust-by-example/std/box.html, and https://doc.rust-lang.org/std/boxed/index.html - -error[E0308]: mismatched types - --> $DIR/issue-111011.rs:11:9 - | -LL | bar(async move || {}); - | --- ^^^^^^^^^^^^^^^^ expected `Box _>`, found closure - | | - | arguments to this function are incorrect - | - = note: expected struct `Box<(dyn FnOnce() -> _ + 'static)>` - found closure `{closure@$DIR/issue-111011.rs:11:9: 11:22}` - = note: for more on the distinction between the stack and the heap, read https://doc.rust-lang.org/book/ch15-01-box.html, https://doc.rust-lang.org/rust-by-example/std/box.html, and https://doc.rust-lang.org/std/boxed/index.html -note: function defined here - --> $DIR/issue-111011.rs:7:4 - | -LL | fn bar(x: Box X>) {} - | ^^^ ------------------------- -help: store this in the heap by calling `Box::new` - | -LL | bar(Box::new(async move || {})); - | +++++++++ + - -error: aborting due to 2 previous errors - -For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/issues/auxiliary/issue-111011.rs b/tests/ui/suggestions/dont-suggest-boxing-async-closure-body.rs similarity index 53% rename from tests/ui/issues/auxiliary/issue-111011.rs rename to tests/ui/suggestions/dont-suggest-boxing-async-closure-body.rs index 0c1a8ce1cf6e..47a590668dde 100644 --- a/tests/ui/issues/auxiliary/issue-111011.rs +++ b/tests/ui/suggestions/dont-suggest-boxing-async-closure-body.rs @@ -1,10 +1,12 @@ //@ edition:2021 +// issue: https://github.com/rust-lang/rust/issues/111011 fn foo(x: impl FnOnce() -> Box) {} // just to make sure async closures can still be suggested for boxing. fn bar(x: Box X>) {} fn main() { - foo(async move || {}); //~ ERROR mismatched types + foo(async move || {}); + //~^ ERROR expected `{async closure@dont-suggest-boxing-async-closure-body.rs:9:9}` to be a closure that returns `Box<_>` bar(async move || {}); //~ ERROR mismatched types } diff --git a/tests/ui/suggestions/dont-suggest-boxing-async-closure-body.stderr b/tests/ui/suggestions/dont-suggest-boxing-async-closure-body.stderr new file mode 100644 index 000000000000..db2a3b9a9c15 --- /dev/null +++ b/tests/ui/suggestions/dont-suggest-boxing-async-closure-body.stderr @@ -0,0 +1,41 @@ +error[E0271]: expected `{async closure@dont-suggest-boxing-async-closure-body.rs:9:9}` to be a closure that returns `Box<_>`, but it returns `{async closure body@$DIR/dont-suggest-boxing-async-closure-body.rs:9:23: 9:25}` + --> $DIR/dont-suggest-boxing-async-closure-body.rs:9:9 + | +LL | foo(async move || {}); + | --- ^^^^^^^^^^^^^^^^ expected `Box<_>`, found `async` closure body + | | + | required by a bound introduced by this call + | + = note: expected struct `Box<_>` + found `async` closure body `{async closure body@$DIR/dont-suggest-boxing-async-closure-body.rs:9:23: 9:25}` +note: required by a bound in `foo` + --> $DIR/dont-suggest-boxing-async-closure-body.rs:4:31 + | +LL | fn foo(x: impl FnOnce() -> Box) {} + | ^^^^^^ required by this bound in `foo` + +error[E0308]: mismatched types + --> $DIR/dont-suggest-boxing-async-closure-body.rs:11:9 + | +LL | bar(async move || {}); + | --- ^^^^^^^^^^^^^^^^ expected `Box _>`, found `{async closure@dont-suggest-boxing-async-closure-body.rs:11:9}` + | | + | arguments to this function are incorrect + | + = note: expected struct `Box<(dyn FnOnce() -> _ + 'static)>` + found closure `{async closure@$DIR/dont-suggest-boxing-async-closure-body.rs:11:9: 11:22}` + = note: for more on the distinction between the stack and the heap, read https://doc.rust-lang.org/book/ch15-01-box.html, https://doc.rust-lang.org/rust-by-example/std/box.html, and https://doc.rust-lang.org/std/boxed/index.html +note: function defined here + --> $DIR/dont-suggest-boxing-async-closure-body.rs:6:4 + | +LL | fn bar(x: Box X>) {} + | ^^^ ------------------------- +help: store this in the heap by calling `Box::new` + | +LL | bar(Box::new(async move || {})); + | +++++++++ + + +error: aborting due to 2 previous errors + +Some errors have detailed explanations: E0271, E0308. +For more information about an error, try `rustc --explain E0271`. From 05364239a802375f8806827c322331a23bc90fa9 Mon Sep 17 00:00:00 2001 From: usamoi Date: Wed, 22 Jan 2025 20:11:24 +0800 Subject: [PATCH 75/81] fix doc for std::sync::mpmc --- library/std/src/sync/mpmc/mod.rs | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/library/std/src/sync/mpmc/mod.rs b/library/std/src/sync/mpmc/mod.rs index 0cf4902d6d59..00966ee3ecff 100644 --- a/library/std/src/sync/mpmc/mod.rs +++ b/library/std/src/sync/mpmc/mod.rs @@ -18,7 +18,7 @@ //! infinite buffer. //! //! 2. A synchronous, bounded channel. The [`sync_channel`] function will -//! return a `(SyncSender, Receiver)` tuple where the storage for pending +//! return a `(Sender, Receiver)` tuple where the storage for pending //! messages is a pre-allocated buffer of a fixed size. All sends will be //! **synchronous** by blocking until there is buffer space available. Note //! that a bound of 0 is allowed, causing the channel to become a "rendezvous" @@ -360,9 +360,17 @@ impl Sender { /// that a return value of [`Err`] means that the data will never be /// received, but a return value of [`Ok`] does *not* mean that the data /// will be received. It is possible for the corresponding receiver to - /// hang up immediately after this function returns [`Ok`]. + /// hang up immediately after this function returns [`Ok`]. However, if + /// the channel is zero-capacity, it acts as a rendezvous channel and a + /// return value of [`Ok`] means that the data has been received. /// - /// This method will never block the current thread. + /// If the channel is full and not disconnected, this call will block until + /// the send operation can proceed. If the channel becomes disconnected, + /// this call will wake up and return an error. The returned error contains + /// the original message. + /// + /// If called on a zero-capacity channel, this method will wait for a receive + /// operation to appear on the other side of the channel. /// /// # Examples /// @@ -650,7 +658,7 @@ impl fmt::Debug for Sender { } /// The receiving half of Rust's [`channel`] (or [`sync_channel`]) type. -/// Different threads can share this [`Sender`] by cloning it. +/// Different threads can share this [`Receiver`] by cloning it. /// /// Messages sent to the channel can be retrieved using [`recv`]. /// From 97311a8969d3014b362fe0aaaccb956da840d5f5 Mon Sep 17 00:00:00 2001 From: jyn Date: Sun, 26 Jan 2025 11:20:05 -0500 Subject: [PATCH 76/81] Downgrade `linker-warnings` to allow-by-default This needs more time to bake before we turn it on. Turning it on early risks people silencing the warning indefinitely, before we have the chance to make it less noisy. --- compiler/rustc_lint_defs/src/builtin.rs | 18 +++++++++++++----- tests/run-make/linker-warning/rmake.rs | 1 + .../rust-lld-by-default-beta-stable/rmake.rs | 2 +- .../rust-lld-by-default-nightly/rmake.rs | 9 +++++++-- tests/run-make/rust-lld-custom-target/rmake.rs | 2 ++ tests/run-make/rust-lld/rmake.rs | 10 ++++++++-- 6 files changed, 32 insertions(+), 10 deletions(-) diff --git a/compiler/rustc_lint_defs/src/builtin.rs b/compiler/rustc_lint_defs/src/builtin.rs index 8bf01adc5b59..5b4a1f174cbb 100644 --- a/compiler/rustc_lint_defs/src/builtin.rs +++ b/compiler/rustc_lint_defs/src/builtin.rs @@ -4091,6 +4091,7 @@ declare_lint! { /// ### Example /// /// ```rust,ignore (needs CLI args, platform-specific) + /// #[warn(linker_messages)] /// extern "C" { /// fn foo(); /// } @@ -4104,17 +4105,24 @@ declare_lint! { /// >>> referenced by rust_out.69edbd30df4ae57d-cgu.0 /// >>> rust_out.rust_out.69edbd30df4ae57d-cgu.0.rcgu.o:(rust_out::main::h3a90094b06757803) /// | - /// = note: `#[warn(linker_messages)]` on by default - /// + /// note: the lint level is defined here + /// --> warn.rs:1:9 + /// | + /// 1 | #![warn(linker_messages)] + /// | ^^^^^^^^^^^^^^^ /// warning: 1 warning emitted /// ``` /// /// ### Explanation /// - /// Linkers emit platform-specific and program-specific warnings that cannot be predicted in advance by the rust compiler. - /// They are forwarded by default, but can be disabled by adding `#![allow(linker_messages)]` at the crate root. + /// Linkers emit platform-specific and program-specific warnings that cannot be predicted in + /// advance by the Rust compiler. Such messages are ignored by default for now. While linker + /// warnings could be very useful they have been ignored for many years by essentially all + /// users, so we need to do a bit more work than just surfacing their text to produce a clear + /// and actionable warning of similar quality to our other diagnostics. See this tracking + /// issue for more details: . pub LINKER_MESSAGES, - Warn, + Allow, "warnings emitted at runtime by the target-specific linker program" } diff --git a/tests/run-make/linker-warning/rmake.rs b/tests/run-make/linker-warning/rmake.rs index 1bd099d2aee5..30387af428c6 100644 --- a/tests/run-make/linker-warning/rmake.rs +++ b/tests/run-make/linker-warning/rmake.rs @@ -8,6 +8,7 @@ fn run_rustc() -> Rustc { // Make sure we use a consistent value. .arg("-Clink-self-contained=-linker") .arg("-Zunstable-options") + .arg("-Wlinker-messages") .output("main") .linker("./fake-linker"); if run_make_support::target() == "x86_64-unknown-linux-gnu" { diff --git a/tests/run-make/rust-lld-by-default-beta-stable/rmake.rs b/tests/run-make/rust-lld-by-default-beta-stable/rmake.rs index d2f1e8b253a7..263bb9b2e200 100644 --- a/tests/run-make/rust-lld-by-default-beta-stable/rmake.rs +++ b/tests/run-make/rust-lld-by-default-beta-stable/rmake.rs @@ -12,7 +12,7 @@ use run_make_support::rustc; fn main() { // A regular compilation should not use rust-lld by default. We'll check that by asking the // linker to display its version number with a link-arg. - let output = rustc().link_arg("-Wl,-v").input("main.rs").run(); + let output = rustc().arg("-Wlinker-messages").link_arg("-Wl,-v").input("main.rs").run(); assert!( !find_lld_version_in_logs(output.stderr_utf8()), "the LLD version string should not be present in the output logs:\n{}", diff --git a/tests/run-make/rust-lld-by-default-nightly/rmake.rs b/tests/run-make/rust-lld-by-default-nightly/rmake.rs index a25a69b859ba..7a0a08863dd3 100644 --- a/tests/run-make/rust-lld-by-default-nightly/rmake.rs +++ b/tests/run-make/rust-lld-by-default-nightly/rmake.rs @@ -12,7 +12,7 @@ use run_make_support::rustc; fn main() { // A regular compilation should use rust-lld by default. We'll check that by asking the linker // to display its version number with a link-arg. - let output = rustc().link_arg("-Wl,-v").input("main.rs").run(); + let output = rustc().arg("-Wlinker-messages").link_arg("-Wl,-v").input("main.rs").run(); assert!( find_lld_version_in_logs(output.stderr_utf8()), "the LLD version string should be present in the output logs:\n{}", @@ -20,7 +20,12 @@ fn main() { ); // But it can still be disabled by turning the linker feature off. - let output = rustc().link_arg("-Wl,-v").arg("-Zlinker-features=-lld").input("main.rs").run(); + let output = rustc() + .arg("-Wlinker-messages") + .link_arg("-Wl,-v") + .arg("-Zlinker-features=-lld") + .input("main.rs") + .run(); assert!( !find_lld_version_in_logs(output.stderr_utf8()), "the LLD version string should not be present in the output logs:\n{}", diff --git a/tests/run-make/rust-lld-custom-target/rmake.rs b/tests/run-make/rust-lld-custom-target/rmake.rs index a6f936ba6e5c..993a248ad00d 100644 --- a/tests/run-make/rust-lld-custom-target/rmake.rs +++ b/tests/run-make/rust-lld-custom-target/rmake.rs @@ -16,6 +16,7 @@ fn main() { // the linker to display its version number with a link-arg. let output = rustc() .crate_type("cdylib") + .arg("-Wlinker-messages") .target("custom-target.json") .link_arg("-Wl,-v") .input("lib.rs") @@ -29,6 +30,7 @@ fn main() { // But it can also be disabled via linker features. let output = rustc() .crate_type("cdylib") + .arg("-Wlinker-messages") .target("custom-target.json") .arg("-Zlinker-features=-lld") .link_arg("-Wl,-v") diff --git a/tests/run-make/rust-lld/rmake.rs b/tests/run-make/rust-lld/rmake.rs index 76b15ab1799b..e5ae94353884 100644 --- a/tests/run-make/rust-lld/rmake.rs +++ b/tests/run-make/rust-lld/rmake.rs @@ -17,6 +17,7 @@ fn main() { .arg("-Zlinker-features=+lld") .arg("-Clink-self-contained=+linker") .arg("-Zunstable-options") + .arg("-Wlinker-messages") .link_arg(linker_version_flag) .input("main.rs") .run(); @@ -27,8 +28,12 @@ fn main() { ); // It should not be used when we explicitly opt-out of lld. - let output = - rustc().link_arg(linker_version_flag).arg("-Zlinker-features=-lld").input("main.rs").run(); + let output = rustc() + .link_arg(linker_version_flag) + .arg("-Zlinker-features=-lld") + .arg("-Wlinker-messages") + .input("main.rs") + .run(); assert!( !find_lld_version_in_logs(output.stderr_utf8()), "the LLD version string should not be present in the output logs:\n{}", @@ -44,6 +49,7 @@ fn main() { .arg("-Zlinker-features=-lld") .arg("-Zlinker-features=+lld") .arg("-Zlinker-features=-lld,+lld") + .arg("-Wlinker-messages") .input("main.rs") .run(); assert!( From b24f6745203fcf7e177f577444a0cdbae6411b41 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Mon, 27 Jan 2025 08:11:02 +0000 Subject: [PATCH 77/81] Change `collect_and_partition_mono_items` tuple return type to a struct --- .../rustc_codegen_cranelift/src/driver/aot.rs | 2 +- .../src/coverageinfo/mapgen.rs | 6 ++++-- .../src/assert_module_sources.rs | 8 ++++++-- .../rustc_codegen_ssa/src/back/symbol_export.rs | 2 +- compiler/rustc_codegen_ssa/src/base.rs | 4 ++-- compiler/rustc_middle/src/mir/mono.rs | 8 +++++++- compiler/rustc_middle/src/query/erase.rs | 1 + compiler/rustc_middle/src/query/mod.rs | 6 +++--- compiler/rustc_monomorphize/src/partitioning.rs | 17 ++++++++--------- 9 files changed, 33 insertions(+), 21 deletions(-) diff --git a/compiler/rustc_codegen_cranelift/src/driver/aot.rs b/compiler/rustc_codegen_cranelift/src/driver/aot.rs index 7d5592daac1c..27adf6318e22 100644 --- a/compiler/rustc_codegen_cranelift/src/driver/aot.rs +++ b/compiler/rustc_codegen_cranelift/src/driver/aot.rs @@ -676,7 +676,7 @@ pub(crate) fn run_aot( .to_owned(); let cgus = if tcx.sess.opts.output_types.should_codegen() { - tcx.collect_and_partition_mono_items(()).1 + tcx.collect_and_partition_mono_items(()).codegen_units } else { // If only `--emit metadata` is used, we shouldn't perform any codegen. // Also `tcx.collect_and_partition_mono_items` may panic in that case. diff --git a/compiler/rustc_codegen_llvm/src/coverageinfo/mapgen.rs b/compiler/rustc_codegen_llvm/src/coverageinfo/mapgen.rs index b3ad2a0e4098..fd22421c7fcf 100644 --- a/compiler/rustc_codegen_llvm/src/coverageinfo/mapgen.rs +++ b/compiler/rustc_codegen_llvm/src/coverageinfo/mapgen.rs @@ -9,6 +9,7 @@ use rustc_data_structures::fx::{FxHashSet, FxIndexMap}; use rustc_hir::def_id::{DefId, LocalDefId}; use rustc_index::IndexVec; use rustc_middle::mir; +use rustc_middle::mir::mono::MonoItemPartitions; use rustc_middle::ty::{self, TyCtxt}; use rustc_session::RemapFileNameExt; use rustc_session::config::RemapPathScopeComponents; @@ -297,12 +298,13 @@ struct UsageSets<'tcx> { /// Prepare sets of definitions that are relevant to deciding whether something /// is an "unused function" for coverage purposes. fn prepare_usage_sets<'tcx>(tcx: TyCtxt<'tcx>) -> UsageSets<'tcx> { - let (all_mono_items, cgus) = tcx.collect_and_partition_mono_items(()); + let MonoItemPartitions { all_mono_items, codegen_units } = + tcx.collect_and_partition_mono_items(()); // Obtain a MIR body for each function participating in codegen, via an // arbitrary instance. let mut def_ids_seen = FxHashSet::default(); - let def_and_mir_for_all_mono_fns = cgus + let def_and_mir_for_all_mono_fns = codegen_units .iter() .flat_map(|cgu| cgu.items().keys()) .filter_map(|item| match item { diff --git a/compiler/rustc_codegen_ssa/src/assert_module_sources.rs b/compiler/rustc_codegen_ssa/src/assert_module_sources.rs index ab65319e3d3e..27331ce4ca66 100644 --- a/compiler/rustc_codegen_ssa/src/assert_module_sources.rs +++ b/compiler/rustc_codegen_ssa/src/assert_module_sources.rs @@ -46,8 +46,12 @@ pub fn assert_module_sources(tcx: TyCtxt<'_>, set_reuse: &dyn Fn(&mut CguReuseTr return; } - let available_cgus = - tcx.collect_and_partition_mono_items(()).1.iter().map(|cgu| cgu.name()).collect(); + let available_cgus = tcx + .collect_and_partition_mono_items(()) + .codegen_units + .iter() + .map(|cgu| cgu.name()) + .collect(); let mut ams = AssertModuleSource { tcx, diff --git a/compiler/rustc_codegen_ssa/src/back/symbol_export.rs b/compiler/rustc_codegen_ssa/src/back/symbol_export.rs index 60ab29193525..f8f7bb2dbc69 100644 --- a/compiler/rustc_codegen_ssa/src/back/symbol_export.rs +++ b/compiler/rustc_codegen_ssa/src/back/symbol_export.rs @@ -293,7 +293,7 @@ fn exported_symbols_provider_local( // external linkage is enough for monomorphization to be linked to. let need_visibility = tcx.sess.target.dynamic_linking && !tcx.sess.target.only_cdylib; - let (_, cgus) = tcx.collect_and_partition_mono_items(()); + let cgus = tcx.collect_and_partition_mono_items(()).codegen_units; // The symbols created in this loop are sorted below it #[allow(rustc::potential_query_instability)] diff --git a/compiler/rustc_codegen_ssa/src/base.rs b/compiler/rustc_codegen_ssa/src/base.rs index 014bdeb46ad5..e438bd70c510 100644 --- a/compiler/rustc_codegen_ssa/src/base.rs +++ b/compiler/rustc_codegen_ssa/src/base.rs @@ -619,7 +619,7 @@ pub fn codegen_crate( // Run the monomorphization collector and partition the collected items into // codegen units. - let codegen_units = tcx.collect_and_partition_mono_items(()).1; + let codegen_units = tcx.collect_and_partition_mono_items(()).codegen_units; // Force all codegen_unit queries so they are already either red or green // when compile_codegen_unit accesses them. We are not able to re-execute @@ -1051,7 +1051,7 @@ pub(crate) fn provide(providers: &mut Providers) { config::OptLevel::SizeMin => config::OptLevel::Default, }; - let (defids, _) = tcx.collect_and_partition_mono_items(cratenum); + let defids = tcx.collect_and_partition_mono_items(cratenum).all_mono_items; let any_for_speed = defids.items().any(|id| { let CodegenFnAttrs { optimize, .. } = tcx.codegen_fn_attrs(*id); diff --git a/compiler/rustc_middle/src/mir/mono.rs b/compiler/rustc_middle/src/mir/mono.rs index 111c3b6956a2..3eccf56d8c4d 100644 --- a/compiler/rustc_middle/src/mir/mono.rs +++ b/compiler/rustc_middle/src/mir/mono.rs @@ -8,7 +8,7 @@ use rustc_data_structures::fx::FxIndexMap; use rustc_data_structures::stable_hasher::{Hash128, HashStable, StableHasher, ToStableHashKey}; use rustc_data_structures::unord::UnordMap; use rustc_hir::ItemId; -use rustc_hir::def_id::{CrateNum, DefId, LOCAL_CRATE}; +use rustc_hir::def_id::{CrateNum, DefId, DefIdSet, LOCAL_CRATE}; use rustc_index::Idx; use rustc_macros::{HashStable, TyDecodable, TyEncodable}; use rustc_query_system::ich::StableHashingContext; @@ -247,6 +247,12 @@ impl ToStableHashKey> for MonoItem<'_> { } } +#[derive(Debug, HashStable, Copy, Clone)] +pub struct MonoItemPartitions<'tcx> { + pub codegen_units: &'tcx [CodegenUnit<'tcx>], + pub all_mono_items: &'tcx DefIdSet, +} + #[derive(Debug, HashStable)] pub struct CodegenUnit<'tcx> { /// A name for this CGU. Incremental compilation requires that diff --git a/compiler/rustc_middle/src/query/erase.rs b/compiler/rustc_middle/src/query/erase.rs index 1676afb4b6ec..14f871cbbdcb 100644 --- a/compiler/rustc_middle/src/query/erase.rs +++ b/compiler/rustc_middle/src/query/erase.rs @@ -349,6 +349,7 @@ tcx_lifetime! { rustc_middle::mir::interpret::GlobalId, rustc_middle::mir::interpret::LitToConstInput, rustc_middle::mir::interpret::EvalStaticInitializerRawResult, + rustc_middle::mir::mono::MonoItemPartitions, rustc_middle::traits::query::MethodAutoderefStepsResult, rustc_middle::traits::query::type_op::AscribeUserType, rustc_middle::traits::query::type_op::Eq, diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs index 17e1fe35bba0..e27a98236390 100644 --- a/compiler/rustc_middle/src/query/mod.rs +++ b/compiler/rustc_middle/src/query/mod.rs @@ -23,7 +23,7 @@ use rustc_data_structures::unord::{UnordMap, UnordSet}; use rustc_errors::ErrorGuaranteed; use rustc_hir::def::{DefKind, DocLinkResMap}; use rustc_hir::def_id::{ - CrateNum, DefId, DefIdMap, DefIdSet, LocalDefId, LocalDefIdMap, LocalDefIdSet, LocalModDefId, + CrateNum, DefId, DefIdMap, LocalDefId, LocalDefIdMap, LocalDefIdSet, LocalModDefId, }; use rustc_hir::lang_items::{LangItem, LanguageItems}; use rustc_hir::{Crate, ItemLocalId, ItemLocalMap, TraitCandidate}; @@ -58,7 +58,7 @@ use crate::mir::interpret::{ EvalStaticInitializerRawResult, EvalToAllocationRawResult, EvalToConstValueResult, EvalToValTreeResult, GlobalId, LitToConstInput, }; -use crate::mir::mono::{CodegenUnit, CollectionMode, MonoItem}; +use crate::mir::mono::{CodegenUnit, CollectionMode, MonoItem, MonoItemPartitions}; use crate::query::erase::{Erase, erase, restore}; use crate::query::plumbing::{ CyclePlaceholder, DynamicQuery, query_ensure, query_ensure_error_guaranteed, query_get_at, @@ -2166,7 +2166,7 @@ rustc_queries! { separate_provide_extern } - query collect_and_partition_mono_items(_: ()) -> (&'tcx DefIdSet, &'tcx [CodegenUnit<'tcx>]) { + query collect_and_partition_mono_items(_: ()) -> MonoItemPartitions<'tcx> { eval_always desc { "collect_and_partition_mono_items" } } diff --git a/compiler/rustc_monomorphize/src/partitioning.rs b/compiler/rustc_monomorphize/src/partitioning.rs index 7b1796634308..e08c348a64d7 100644 --- a/compiler/rustc_monomorphize/src/partitioning.rs +++ b/compiler/rustc_monomorphize/src/partitioning.rs @@ -110,7 +110,7 @@ use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags; use rustc_middle::middle::exported_symbols::{SymbolExportInfo, SymbolExportLevel}; use rustc_middle::mir::mono::{ CodegenUnit, CodegenUnitNameBuilder, InstantiationMode, Linkage, MonoItem, MonoItemData, - Visibility, + MonoItemPartitions, Visibility, }; use rustc_middle::ty::print::{characteristic_def_id_of_type, with_no_trimmed_paths}; use rustc_middle::ty::{self, InstanceKind, TyCtxt}; @@ -1114,7 +1114,7 @@ where } } -fn collect_and_partition_mono_items(tcx: TyCtxt<'_>, (): ()) -> (&DefIdSet, &[CodegenUnit<'_>]) { +fn collect_and_partition_mono_items(tcx: TyCtxt<'_>, (): ()) -> MonoItemPartitions<'_> { let collection_strategy = match tcx.sess.opts.unstable_opts.print_mono_items { Some(ref s) => { let mode = s.to_lowercase(); @@ -1236,7 +1236,7 @@ fn collect_and_partition_mono_items(tcx: TyCtxt<'_>, (): ()) -> (&DefIdSet, &[Co } } - (tcx.arena.alloc(mono_items), codegen_units) + MonoItemPartitions { all_mono_items: tcx.arena.alloc(mono_items), codegen_units } } /// Outputs stats about instantiation counts and estimated size, per `MonoItem`'s @@ -1319,14 +1319,13 @@ fn dump_mono_items_stats<'tcx>( pub(crate) fn provide(providers: &mut Providers) { providers.collect_and_partition_mono_items = collect_and_partition_mono_items; - providers.is_codegened_item = |tcx, def_id| { - let (all_mono_items, _) = tcx.collect_and_partition_mono_items(()); - all_mono_items.contains(&def_id) - }; + providers.is_codegened_item = + |tcx, def_id| tcx.collect_and_partition_mono_items(()).all_mono_items.contains(&def_id); providers.codegen_unit = |tcx, name| { - let (_, all) = tcx.collect_and_partition_mono_items(()); - all.iter() + tcx.collect_and_partition_mono_items(()) + .codegen_units + .iter() .find(|cgu| cgu.name() == name) .unwrap_or_else(|| panic!("failed to find cgu with name {name:?}")) }; From f630f7f410e38e55ed095a3ccc0131ddccbf6a3f Mon Sep 17 00:00:00 2001 From: Marijn Schouten Date: Mon, 20 Jan 2025 15:37:52 +0100 Subject: [PATCH 78/81] Clarify WindowsMut (Lending)Iterator fixes 133628 --- library/core/src/slice/mod.rs | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/library/core/src/slice/mod.rs b/library/core/src/slice/mod.rs index ba5746d0adea..1993a7491e10 100644 --- a/library/core/src/slice/mod.rs +++ b/library/core/src/slice/mod.rs @@ -1099,10 +1099,15 @@ impl [T] { /// assert!(iter.next().is_none()); /// ``` /// - /// There's no `windows_mut`, as that existing would let safe code violate the - /// "only one `&mut` at a time to the same thing" rule. However, you can sometimes - /// use [`Cell::as_slice_of_cells`](crate::cell::Cell::as_slice_of_cells) in - /// conjunction with `windows` to accomplish something similar: + /// Because the [Iterator] trait cannot represent the required lifetimes, + /// there is no `windows_mut` analog to `windows`; + /// `[0,1,2].windows_mut(2).collect()` would violate [the rules of references] + /// (though a [LendingIterator] analog is possible). You can sometimes use + /// [`Cell::as_slice_of_cells`](crate::cell::Cell::as_slice_of_cells) in + /// conjunction with `windows` instead: + /// + /// [the rules of references]: https://doc.rust-lang.org/book/ch04-02-references-and-borrowing.html#the-rules-of-references + /// [LendingIterator]: https://blog.rust-lang.org/2022/10/28/gats-stabilization.html /// ``` /// use std::cell::Cell; /// From 74234de9b4ff8f5b1474718f4a09ad177afc4b3f Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Tue, 28 Jan 2025 03:29:27 +0100 Subject: [PATCH 79/81] Preparing for merge from rustc --- src/tools/miri/rust-version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/miri/rust-version b/src/tools/miri/rust-version index 0d405f532fcd..e548b44d8c2c 100644 --- a/src/tools/miri/rust-version +++ b/src/tools/miri/rust-version @@ -1 +1 @@ -2f0ad2a71e4a4528bb80bcb24bf8fa4e50cb87c2 +2f348cb7ce4063fa4eb40038e6ada3c5214717bd From 6b699ccee499949b5e4e222976e1ac8887412a5c Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Thu, 30 Jan 2025 13:44:13 +0100 Subject: [PATCH 80/81] float::min/max: mention the non-determinism around signed 0 --- library/core/src/num/f128.rs | 6 ++++-- library/core/src/num/f16.rs | 6 ++++-- library/core/src/num/f32.rs | 6 ++++-- library/core/src/num/f64.rs | 6 ++++-- 4 files changed, 16 insertions(+), 8 deletions(-) diff --git a/library/core/src/num/f128.rs b/library/core/src/num/f128.rs index 8fb1588e60b3..5e45974b3d42 100644 --- a/library/core/src/num/f128.rs +++ b/library/core/src/num/f128.rs @@ -670,7 +670,8 @@ impl f128 { /// If one of the arguments is NaN, then the other argument is returned. /// This follows the IEEE 754-2008 semantics for maxNum, except for handling of signaling NaNs; /// this function handles all NaNs the same way and avoids maxNum's problems with associativity. - /// This also matches the behavior of libm’s fmax. + /// This also matches the behavior of libm’s fmax. In particular, if the inputs compare equal + /// (such as for the case of `+0.0` and `-0.0`), either input may be returned non-deterministically. /// /// ``` /// #![feature(f128)] @@ -696,7 +697,8 @@ impl f128 { /// If one of the arguments is NaN, then the other argument is returned. /// This follows the IEEE 754-2008 semantics for minNum, except for handling of signaling NaNs; /// this function handles all NaNs the same way and avoids minNum's problems with associativity. - /// This also matches the behavior of libm’s fmin. + /// This also matches the behavior of libm’s fmin. In particular, if the inputs compare equal + /// (such as for the case of `+0.0` and `-0.0`), either input may be returned non-deterministically. /// /// ``` /// #![feature(f128)] diff --git a/library/core/src/num/f16.rs b/library/core/src/num/f16.rs index 8c2af74b8f84..e3176cd16885 100644 --- a/library/core/src/num/f16.rs +++ b/library/core/src/num/f16.rs @@ -662,7 +662,8 @@ impl f16 { /// If one of the arguments is NaN, then the other argument is returned. /// This follows the IEEE 754-2008 semantics for maxNum, except for handling of signaling NaNs; /// this function handles all NaNs the same way and avoids maxNum's problems with associativity. - /// This also matches the behavior of libm’s fmax. + /// This also matches the behavior of libm’s fmax. In particular, if the inputs compare equal + /// (such as for the case of `+0.0` and `-0.0`), either input may be returned non-deterministically. /// /// ``` /// #![feature(f16)] @@ -687,7 +688,8 @@ impl f16 { /// If one of the arguments is NaN, then the other argument is returned. /// This follows the IEEE 754-2008 semantics for minNum, except for handling of signaling NaNs; /// this function handles all NaNs the same way and avoids minNum's problems with associativity. - /// This also matches the behavior of libm’s fmin. + /// This also matches the behavior of libm’s fmin. In particular, if the inputs compare equal + /// (such as for the case of `+0.0` and `-0.0`), either input may be returned non-deterministically. /// /// ``` /// #![feature(f16)] diff --git a/library/core/src/num/f32.rs b/library/core/src/num/f32.rs index 817bedbd44f9..4d42997369ff 100644 --- a/library/core/src/num/f32.rs +++ b/library/core/src/num/f32.rs @@ -874,7 +874,8 @@ impl f32 { /// If one of the arguments is NaN, then the other argument is returned. /// This follows the IEEE 754-2008 semantics for maxNum, except for handling of signaling NaNs; /// this function handles all NaNs the same way and avoids maxNum's problems with associativity. - /// This also matches the behavior of libm’s fmax. + /// This also matches the behavior of libm’s fmax. In particular, if the inputs compare equal + /// (such as for the case of `+0.0` and `-0.0`), either input may be returned non-deterministically. /// /// ``` /// let x = 1.0f32; @@ -895,7 +896,8 @@ impl f32 { /// If one of the arguments is NaN, then the other argument is returned. /// This follows the IEEE 754-2008 semantics for minNum, except for handling of signaling NaNs; /// this function handles all NaNs the same way and avoids minNum's problems with associativity. - /// This also matches the behavior of libm’s fmin. + /// This also matches the behavior of libm’s fmin. In particular, if the inputs compare equal + /// (such as for the case of `+0.0` and `-0.0`), either input may be returned non-deterministically. /// /// ``` /// let x = 1.0f32; diff --git a/library/core/src/num/f64.rs b/library/core/src/num/f64.rs index 1b0651a0def0..907971d303ff 100644 --- a/library/core/src/num/f64.rs +++ b/library/core/src/num/f64.rs @@ -892,7 +892,8 @@ impl f64 { /// If one of the arguments is NaN, then the other argument is returned. /// This follows the IEEE 754-2008 semantics for maxNum, except for handling of signaling NaNs; /// this function handles all NaNs the same way and avoids maxNum's problems with associativity. - /// This also matches the behavior of libm’s fmax. + /// This also matches the behavior of libm’s fmax. In particular, if the inputs compare equal + /// (such as for the case of `+0.0` and `-0.0`), either input may be returned non-deterministically. /// /// ``` /// let x = 1.0_f64; @@ -913,7 +914,8 @@ impl f64 { /// If one of the arguments is NaN, then the other argument is returned. /// This follows the IEEE 754-2008 semantics for minNum, except for handling of signaling NaNs; /// this function handles all NaNs the same way and avoids minNum's problems with associativity. - /// This also matches the behavior of libm’s fmin. + /// This also matches the behavior of libm’s fmin. In particular, if the inputs compare equal + /// (such as for the case of `+0.0` and `-0.0`), either input may be returned non-deterministically. /// /// ``` /// let x = 1.0_f64; From 051829eb18b27a4ffab2309901d7bc07bf0e665d Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Tue, 28 Jan 2025 03:36:45 +0100 Subject: [PATCH 81/81] linker messages are no longer warnings by default --- src/tools/miri/ci/ci.sh | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/tools/miri/ci/ci.sh b/src/tools/miri/ci/ci.sh index fb3fc621565e..5583030b490a 100755 --- a/src/tools/miri/ci/ci.sh +++ b/src/tools/miri/ci/ci.sh @@ -14,9 +14,7 @@ function endgroup { begingroup "Building Miri" # Global configuration -# We are getting some odd linker warnings on macOS, make sure they do not fail the build. -# (See .) -export RUSTFLAGS="-D warnings -A linker-messages" +export RUSTFLAGS="-D warnings" export CARGO_INCREMENTAL=0 export CARGO_EXTRA_FLAGS="--locked"

}T8^`s)jmb~0XJqC3?LWA6^Tk~sPhVR8|FXWr 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͗Yp-8l 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 Date: Mon, 20 Jan 2025 18:01:05 +0000 Subject: [PATCH 66/81] Add cache to FoldEscapingRegions --- compiler/rustc_type_ir/src/ty_kind/closure.rs | 20 +++++- .../post-mono-higher-ranked-hang-2.rs | 23 +++++++ .../post-mono-higher-ranked-hang-2.stderr | 18 ++++++ .../post-mono-higher-ranked-hang.rs | 63 +++++++++++++++++++ .../post-mono-higher-ranked-hang.stderr | 21 +++++++ 5 files changed, 144 insertions(+), 1 deletion(-) create mode 100644 tests/ui/async-await/async-closures/post-mono-higher-ranked-hang-2.rs create mode 100644 tests/ui/async-await/async-closures/post-mono-higher-ranked-hang-2.stderr create mode 100644 tests/ui/async-await/async-closures/post-mono-higher-ranked-hang.rs create mode 100644 tests/ui/async-await/async-closures/post-mono-higher-ranked-hang.stderr diff --git a/compiler/rustc_type_ir/src/ty_kind/closure.rs b/compiler/rustc_type_ir/src/ty_kind/closure.rs index 10b164eae027..74e4e035c875 100644 --- a/compiler/rustc_type_ir/src/ty_kind/closure.rs +++ b/compiler/rustc_type_ir/src/ty_kind/closure.rs @@ -3,9 +3,10 @@ use std::ops::ControlFlow; use derive_where::derive_where; use rustc_type_ir_macros::{Lift_Generic, TypeFoldable_Generic, TypeVisitable_Generic}; +use crate::data_structures::DelayedMap; use crate::fold::{TypeFoldable, TypeFolder, TypeSuperFoldable, shift_region}; use crate::inherent::*; -use crate::visit::{TypeSuperVisitable, TypeVisitable, TypeVisitor}; +use crate::visit::{TypeSuperVisitable, TypeVisitable, TypeVisitableExt, TypeVisitor}; use crate::{self as ty, Interner}; /// A closure can be modeled as a struct that looks like: @@ -471,6 +472,7 @@ impl CoroutineClosureSignature { interner: cx, region: env_region, debruijn: ty::INNERMOST, + cache: Default::default(), }); Ty::new_tup_from_iter( cx, @@ -498,6 +500,10 @@ struct FoldEscapingRegions { interner: I, debruijn: ty::DebruijnIndex, region: I::Region, + + // Depends on `debruijn` because we may have types with regions of different + // debruijn depths depending on the binders we've entered. + cache: DelayedMap<(ty::DebruijnIndex, I::Ty), I::Ty>, } impl TypeFolder for FoldEscapingRegions { @@ -505,6 +511,18 @@ impl TypeFolder for FoldEscapingRegions { self.interner } + fn fold_ty(&mut self, t: I::Ty) -> I::Ty { + if !t.has_vars_bound_at_or_above(self.debruijn) { + t + } else if let Some(&t) = self.cache.get(&(self.debruijn, t)) { + t + } else { + let res = t.super_fold_with(self); + assert!(self.cache.insert((self.debruijn, t), res)); + res + } + } + fn fold_binder(&mut self, t: ty::Binder) -> ty::Binder where T: TypeFoldable, diff --git a/tests/ui/async-await/async-closures/post-mono-higher-ranked-hang-2.rs b/tests/ui/async-await/async-closures/post-mono-higher-ranked-hang-2.rs new file mode 100644 index 000000000000..4cdf4bf8def6 --- /dev/null +++ b/tests/ui/async-await/async-closures/post-mono-higher-ranked-hang-2.rs @@ -0,0 +1,23 @@ +//@ edition: 2021 +//@ build-fail + +// Regression test for . + +use std::future::Future; +use std::ops::AsyncFn; +use std::pin::Pin; + +fn recur<'l>(closure: &'l impl AsyncFn()) -> Pin + 'l>> { + Box::pin(async move { + let _ = closure(); + let _ = recur(&async || { + //~^ ERROR reached the recursion limit + let _ = closure(); + }); + }) +} + +fn main() { + let closure = async || {}; + let _ = recur(&closure); +} diff --git a/tests/ui/async-await/async-closures/post-mono-higher-ranked-hang-2.stderr b/tests/ui/async-await/async-closures/post-mono-higher-ranked-hang-2.stderr new file mode 100644 index 000000000000..64f4665225ff --- /dev/null +++ b/tests/ui/async-await/async-closures/post-mono-higher-ranked-hang-2.stderr @@ -0,0 +1,18 @@ +error: reached the recursion limit while instantiating `recur::<{async closure@$DIR/post-mono-higher-ranked-hang-2.rs:13:24: 13:32}>` + --> $DIR/post-mono-higher-ranked-hang-2.rs:13:17 + | +LL | let _ = recur(&async || { + | _________________^ +LL | | +LL | | let _ = closure(); +LL | | }); + | |__________^ + | +note: `recur` defined here + --> $DIR/post-mono-higher-ranked-hang-2.rs:10:1 + | +LL | fn recur<'l>(closure: &'l impl AsyncFn()) -> Pin + 'l>> { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 1 previous error + diff --git a/tests/ui/async-await/async-closures/post-mono-higher-ranked-hang.rs b/tests/ui/async-await/async-closures/post-mono-higher-ranked-hang.rs new file mode 100644 index 000000000000..f6ebf787f81b --- /dev/null +++ b/tests/ui/async-await/async-closures/post-mono-higher-ranked-hang.rs @@ -0,0 +1,63 @@ +//@ build-fail +//@ aux-build:block-on.rs +//@ edition:2021 + +// Regression test for . + +extern crate block_on; + +use std::future::Future; +use std::ops::AsyncFnMut; +use std::pin::{Pin, pin}; +use std::task::*; + +trait Db {} + +impl Db for () {} + +struct Env<'db> { + db: &'db (), +} + +#[derive(Debug)] +enum SymPerm<'db> { + Dummy(&'db ()), + Apply(Box>, Box>), +} + +pub struct ToChain<'env, 'db> { + db: &'db dyn crate::Db, + env: &'env Env<'db>, +} + +impl<'env, 'db> ToChain<'env, 'db> { + fn perm_pairs<'l>( + &'l self, + perm: &'l SymPerm<'db>, + yield_chain: &'l mut impl AsyncFnMut(&SymPerm<'db>), + ) -> Pin + 'l>> { + Box::pin(async move { + match perm { + SymPerm::Dummy(_) => yield_chain(perm).await, + SymPerm::Apply(l, r) => { + self.perm_pairs(l, &mut async move |left_pair| { + //~^ ERROR reached the recursion limit while instantiating + self.perm_pairs(r, yield_chain).await + }) + .await + } + } + }) + } +} + +fn main() { + block_on::block_on(async { + let pair = SymPerm::Apply(Box::new(SymPerm::Dummy(&())), Box::new(SymPerm::Dummy(&()))); + ToChain { db: &(), env: &Env { db: &() } } + .perm_pairs(&pair, &mut async |p| { + eprintln!("{p:?}"); + }) + .await; + }); +} diff --git a/tests/ui/async-await/async-closures/post-mono-higher-ranked-hang.stderr b/tests/ui/async-await/async-closures/post-mono-higher-ranked-hang.stderr new file mode 100644 index 000000000000..486e5f941655 --- /dev/null +++ b/tests/ui/async-await/async-closures/post-mono-higher-ranked-hang.stderr @@ -0,0 +1,21 @@ +error: reached the recursion limit while instantiating `ToChain::<'_, '_>::perm_pairs::<{async closure@$DIR/post-mono-higher-ranked-hang.rs:43:45: 43:67}>` + --> $DIR/post-mono-higher-ranked-hang.rs:43:21 + | +LL | / self.perm_pairs(l, &mut async move |left_pair| { +LL | | +LL | | self.perm_pairs(r, yield_chain).await +LL | | }) + | |______________________^ + | +note: `ToChain::<'env, 'db>::perm_pairs` defined here + --> $DIR/post-mono-higher-ranked-hang.rs:34:5 + | +LL | / fn perm_pairs<'l>( +LL | | &'l self, +LL | | perm: &'l SymPerm<'db>, +LL | | yield_chain: &'l mut impl AsyncFnMut(&SymPerm<'db>), +LL | | ) -> Pin + 'l>> { + | |____________________________________________________________^ + +error: aborting due to 1 previous error + From 504d574bc161a5567796076357231aa69e94afc6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=AE=B8=E6=9D=B0=E5=8F=8B=20Jieyou=20Xu=20=28Joe=29?= <39484203+jieyouxu@users.noreply.github.com> Date: Mon, 27 Jan 2025 02:28:35 +0800 Subject: [PATCH 67/81] triagebot: set myself on vacation --- triagebot.toml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/triagebot.toml b/triagebot.toml index 4a09fe116a57..d09d5eceeb84 100644 --- a/triagebot.toml +++ b/triagebot.toml @@ -1025,7 +1025,8 @@ users_on_vacation = [ "nnethercote", "spastorino", "workingjubilee", - "kobzol" + "kobzol", + "jieyouxu", ] [[assign.warn_non_default_branch.exceptions]] From cef97bce7b2a0e6ef2208aaa1ec267b800d646af Mon Sep 17 00:00:00 2001 From: FedericoBruzzone Date: Mon, 6 Jan 2025 11:39:07 +0100 Subject: [PATCH 68/81] Add `TooGeneric` variant to `LayoutError` and emit `Unknown` one - `check-pass` test for a MRE of #135020 - fail test for #135138 - switch to `TooGeneric` for checking CMSE fn signatures - switch to `TooGeneric` for compute `SizeSkeleton` (for transmute) - fix broken tests --- .../rustc_const_eval/src/const_eval/error.rs | 2 +- .../src/hir_ty_lowering/cmse.rs | 8 ++- compiler/rustc_hir_typeck/src/intrinsicck.rs | 2 +- compiler/rustc_middle/messages.ftl | 3 + compiler/rustc_middle/src/error.rs | 3 + compiler/rustc_middle/src/ty/layout.rs | 14 ++-- compiler/rustc_transmute/src/layout/tree.rs | 1 + compiler/rustc_ty_utils/src/layout.rs | 69 ++++++++++++++----- .../html/templates/type_layout.html | 16 +++-- tests/crashes/135020.rs | 11 --- tests/rustdoc/type-layout.rs | 9 ++- tests/ui/enum-discriminant/eval-error.rs | 2 +- tests/ui/enum-discriminant/eval-error.stderr | 12 +++- ...te-instantiation-struct-tail-ice-114484.rs | 2 +- .../layout/base-layout-is-sized-ice-123078.rs | 1 + .../base-layout-is-sized-ice-123078.stderr | 14 +++- tests/ui/layout/invalid-unsized-const-eval.rs | 1 + .../layout/invalid-unsized-const-eval.stderr | 11 ++- ...nvalid-unsized-in-always-sized-tail.stderr | 18 ++++- .../issue-unsized-tail-restatic-ice-122488.rs | 1 + ...ue-unsized-tail-restatic-ice-122488.stderr | 11 ++- ...utable-due-to-trivial-bounds-ice-135138.rs | 11 +++ ...le-due-to-trivial-bounds-ice-135138.stderr | 9 +++ .../unexpected-unsized-field-issue-135020.rs | 7 ++ .../layout/unknown-when-no-type-parameter.rs | 14 ++++ .../unknown-when-no-type-parameter.stderr | 16 +++++ .../unknown-when-ptr-metadata-is-DST.rs | 12 ++++ .../unknown-when-ptr-metadata-is-DST.stderr | 9 +++ .../ice-struct-tail-normalization-113272.rs | 2 +- 29 files changed, 233 insertions(+), 58 deletions(-) delete mode 100644 tests/crashes/135020.rs create mode 100644 tests/ui/layout/uncomputable-due-to-trivial-bounds-ice-135138.rs create mode 100644 tests/ui/layout/uncomputable-due-to-trivial-bounds-ice-135138.stderr create mode 100644 tests/ui/layout/unexpected-unsized-field-issue-135020.rs create mode 100644 tests/ui/layout/unknown-when-no-type-parameter.rs create mode 100644 tests/ui/layout/unknown-when-no-type-parameter.stderr create mode 100644 tests/ui/layout/unknown-when-ptr-metadata-is-DST.rs create mode 100644 tests/ui/layout/unknown-when-ptr-metadata-is-DST.stderr diff --git a/compiler/rustc_const_eval/src/const_eval/error.rs b/compiler/rustc_const_eval/src/const_eval/error.rs index fee7287951d0..cc21a18af3a0 100644 --- a/compiler/rustc_const_eval/src/const_eval/error.rs +++ b/compiler/rustc_const_eval/src/const_eval/error.rs @@ -140,7 +140,7 @@ where // Don't emit a new diagnostic for these errors, they are already reported elsewhere or // should remain silent. err_inval!(AlreadyReported(info)) => ErrorHandled::Reported(info, span), - err_inval!(Layout(LayoutError::Unknown(_))) | err_inval!(TooGeneric) => { + err_inval!(Layout(LayoutError::TooGeneric(_))) | err_inval!(TooGeneric) => { ErrorHandled::TooGeneric(span) } err_inval!(Layout(LayoutError::ReferencesError(guar))) => { diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/cmse.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/cmse.rs index 394719314612..4c8f2735b979 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/cmse.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/cmse.rs @@ -201,7 +201,7 @@ fn should_emit_generic_error<'tcx>(abi: ExternAbi, layout_err: &'tcx LayoutError use LayoutError::*; match layout_err { - Unknown(ty) => { + TooGeneric(ty) => { match abi { ExternAbi::CCmseNonSecureCall => { // prevent double reporting of this error @@ -211,7 +211,11 @@ fn should_emit_generic_error<'tcx>(abi: ExternAbi, layout_err: &'tcx LayoutError _ => bug!("invalid ABI: {abi}"), } } - SizeOverflow(..) | NormalizationFailure(..) | ReferencesError(..) | Cycle(..) => { + Unknown(..) + | SizeOverflow(..) + | NormalizationFailure(..) + | ReferencesError(..) + | Cycle(..) => { false // not our job to report these } } diff --git a/compiler/rustc_hir_typeck/src/intrinsicck.rs b/compiler/rustc_hir_typeck/src/intrinsicck.rs index f4929aae5990..54e9e699353f 100644 --- a/compiler/rustc_hir_typeck/src/intrinsicck.rs +++ b/compiler/rustc_hir_typeck/src/intrinsicck.rs @@ -122,7 +122,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { format!("generic size {size}") } } - Err(LayoutError::Unknown(bad)) => { + Err(LayoutError::TooGeneric(bad)) => { if *bad == ty { "this type does not have a fixed size".to_owned() } else { diff --git a/compiler/rustc_middle/messages.ftl b/compiler/rustc_middle/messages.ftl index 5dd85978f007..8dc529b4d7a2 100644 --- a/compiler/rustc_middle/messages.ftl +++ b/compiler/rustc_middle/messages.ftl @@ -100,6 +100,8 @@ middle_strict_coherence_needs_negative_coherence = to use `strict_coherence` on this trait, the `with_negative_coherence` feature must be enabled .label = due to this attribute +middle_too_generic = `{$ty}` does not have a fixed size + middle_type_length_limit = reached the type-length limit while instantiating `{$shrunk}` middle_unknown_layout = @@ -107,4 +109,5 @@ middle_unknown_layout = middle_values_too_big = values of the type `{$ty}` are too big for the target architecture + middle_written_to_path = the full type name has been written to '{$path}' diff --git a/compiler/rustc_middle/src/error.rs b/compiler/rustc_middle/src/error.rs index 6300d856393c..b0187a1848cf 100644 --- a/compiler/rustc_middle/src/error.rs +++ b/compiler/rustc_middle/src/error.rs @@ -129,6 +129,9 @@ pub enum LayoutError<'tcx> { #[diag(middle_unknown_layout)] Unknown { ty: Ty<'tcx> }, + #[diag(middle_too_generic)] + TooGeneric { ty: Ty<'tcx> }, + #[diag(middle_values_too_big)] Overflow { ty: Ty<'tcx> }, diff --git a/compiler/rustc_middle/src/ty/layout.rs b/compiler/rustc_middle/src/ty/layout.rs index 1e67cdfc32a9..0d41a1d7dbfb 100644 --- a/compiler/rustc_middle/src/ty/layout.rs +++ b/compiler/rustc_middle/src/ty/layout.rs @@ -231,6 +231,7 @@ impl fmt::Display for ValidityRequirement { pub enum LayoutError<'tcx> { Unknown(Ty<'tcx>), SizeOverflow(Ty<'tcx>), + TooGeneric(Ty<'tcx>), NormalizationFailure(Ty<'tcx>, NormalizationError<'tcx>), ReferencesError(ErrorGuaranteed), Cycle(ErrorGuaranteed), @@ -244,6 +245,7 @@ impl<'tcx> LayoutError<'tcx> { match self { Unknown(_) => middle_unknown_layout, SizeOverflow(_) => middle_values_too_big, + TooGeneric(_) => middle_too_generic, NormalizationFailure(_, _) => middle_cannot_be_normalized, Cycle(_) => middle_cycle, ReferencesError(_) => middle_layout_references_error, @@ -257,6 +259,7 @@ impl<'tcx> LayoutError<'tcx> { match self { Unknown(ty) => E::Unknown { ty }, SizeOverflow(ty) => E::Overflow { ty }, + TooGeneric(ty) => E::TooGeneric { ty }, NormalizationFailure(ty, e) => { E::NormalizationFailure { ty, failure_ty: e.get_type_for_failure() } } @@ -272,6 +275,9 @@ impl<'tcx> fmt::Display for LayoutError<'tcx> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match *self { LayoutError::Unknown(ty) => write!(f, "the type `{ty}` has an unknown layout"), + LayoutError::TooGeneric(ty) => { + write!(f, "`{ty}` does not have a fixed size") + } LayoutError::SizeOverflow(ty) => { write!(f, "values of the type `{ty}` are too big for the target architecture") } @@ -350,10 +356,11 @@ impl<'tcx> SizeSkeleton<'tcx> { return Err(tcx.arena.alloc(LayoutError::Unknown(ty))); } } - Err(err @ LayoutError::Unknown(_)) => err, + Err(err @ LayoutError::TooGeneric(_)) => err, // We can't extract SizeSkeleton info from other layout errors Err( e @ LayoutError::Cycle(_) + | e @ LayoutError::Unknown(_) | e @ LayoutError::SizeOverflow(_) | e @ LayoutError::NormalizationFailure(..) | e @ LayoutError::ReferencesError(_), @@ -413,10 +420,9 @@ impl<'tcx> SizeSkeleton<'tcx> { // Alignment is unchanged by arrays. return Ok(SizeSkeleton::Known(Size::from_bytes(size), a)); } - Err(tcx.arena.alloc(LayoutError::Unknown(ty))) + Err(err) } - SizeSkeleton::Pointer { .. } => Err(err), - SizeSkeleton::Generic(_) => Err(tcx.arena.alloc(LayoutError::Unknown(ty))), + SizeSkeleton::Pointer { .. } | SizeSkeleton::Generic(_) => Err(err), } } diff --git a/compiler/rustc_transmute/src/layout/tree.rs b/compiler/rustc_transmute/src/layout/tree.rs index 6ce9969aefe9..b00585d29221 100644 --- a/compiler/rustc_transmute/src/layout/tree.rs +++ b/compiler/rustc_transmute/src/layout/tree.rs @@ -197,6 +197,7 @@ pub(crate) mod rustc { match err { LayoutError::Unknown(..) | LayoutError::ReferencesError(..) + | LayoutError::TooGeneric(..) | LayoutError::NormalizationFailure(..) => Self::UnknownLayout, LayoutError::SizeOverflow(..) => Self::SizeOverflow, LayoutError::Cycle(err) => Self::TypeError(*err), diff --git a/compiler/rustc_ty_utils/src/layout.rs b/compiler/rustc_ty_utils/src/layout.rs index 17be0bd0ab9e..a04c75361183 100644 --- a/compiler/rustc_ty_utils/src/layout.rs +++ b/compiler/rustc_ty_utils/src/layout.rs @@ -104,14 +104,12 @@ fn map_error<'tcx>( // This is sometimes not a compile error if there are trivially false where clauses. // See `tests/ui/layout/trivial-bounds-sized.rs` for an example. assert!(field.layout.is_unsized(), "invalid layout error {err:#?}"); - if !field.ty.is_sized(cx.tcx(), cx.typing_env) { - let guar = cx.tcx().dcx().delayed_bug(format!( + if cx.typing_env.param_env.caller_bounds().is_empty() { + cx.tcx().dcx().delayed_bug(format!( "encountered unexpected unsized field in layout of {ty:?}: {field:#?}" )); - LayoutError::ReferencesError(guar) - } else { - LayoutError::Unknown(ty) } + LayoutError::Unknown(ty) } LayoutCalculatorError::EmptyUnion => { // This is always a compile error. @@ -146,6 +144,35 @@ fn univariant_uninterned<'tcx>( cx.calc.univariant(fields, repr, kind).map_err(|err| map_error(cx, ty, err)) } +fn validate_const_with_value<'tcx>( + const_: ty::Const<'tcx>, + ty: Ty<'tcx>, + cx: &LayoutCx<'tcx>, +) -> Result, &'tcx LayoutError<'tcx>> { + match const_.kind() { + ty::ConstKind::Value(..) => Ok(const_), + ty::ConstKind::Error(guar) => { + return Err(error(cx, LayoutError::ReferencesError(guar))); + } + ty::ConstKind::Param(_) | ty::ConstKind::Expr(_) => { + if !const_.has_param() { + bug!("no generic type found in the type: {ty:?}"); + } + return Err(error(cx, LayoutError::TooGeneric(ty))); + } + ty::ConstKind::Unevaluated(_) => { + if !const_.has_param() { + return Err(error(cx, LayoutError::Unknown(ty))); + } else { + return Err(error(cx, LayoutError::TooGeneric(ty))); + } + } + ty::ConstKind::Infer(_) | ty::ConstKind::Bound(..) | ty::ConstKind::Placeholder(_) => { + bug!("unexpected type: {ty:?}"); + } + } +} + fn layout_of_uncached<'tcx>( cx: &LayoutCx<'tcx>, ty: Ty<'tcx>, @@ -182,12 +209,13 @@ fn layout_of_uncached<'tcx>( &mut layout.backend_repr { if let Some(start) = start { - scalar.valid_range_mut().start = start - .try_to_bits(tcx, cx.typing_env) - .ok_or_else(|| error(cx, LayoutError::Unknown(ty)))?; + scalar.valid_range_mut().start = + validate_const_with_value(start, ty, cx)? + .try_to_bits(tcx, cx.typing_env) + .ok_or_else(|| error(cx, LayoutError::Unknown(ty)))?; } if let Some(end) = end { - let mut end = end + let mut end = validate_const_with_value(end, ty, cx)? .try_to_bits(tcx, cx.typing_env) .ok_or_else(|| error(cx, LayoutError::Unknown(ty)))?; if !include_end { @@ -319,17 +347,13 @@ fn layout_of_uncached<'tcx>( } // Arrays and slices. - ty::Array(element, mut count) => { - if count.has_aliases() { - count = tcx.normalize_erasing_regions(cx.typing_env, count); - if count.has_aliases() { - return Err(error(cx, LayoutError::Unknown(ty))); - } - } - - let count = count + ty::Array(element, count) => { + let count = validate_const_with_value(count, ty, cx)? + .to_valtree() + .0 .try_to_target_usize(tcx) .ok_or_else(|| error(cx, LayoutError::Unknown(ty)))?; + let element = cx.layout_of(element)?; let size = element .size @@ -687,6 +711,9 @@ fn layout_of_uncached<'tcx>( // Types with no meaningful known layout. ty::Alias(..) => { + if ty.has_param() { + return Err(error(cx, LayoutError::TooGeneric(ty))); + } // NOTE(eddyb) `layout_of` query should've normalized these away, // if that was possible, so there's no reason to try again here. return Err(error(cx, LayoutError::Unknown(ty))); @@ -696,7 +723,11 @@ fn layout_of_uncached<'tcx>( bug!("Layout::compute: unexpected type `{}`", ty) } - ty::Placeholder(..) | ty::Param(_) => { + ty::Param(_) => { + return Err(error(cx, LayoutError::TooGeneric(ty))); + } + + ty::Placeholder(..) => { return Err(error(cx, LayoutError::Unknown(ty))); } }) diff --git a/src/librustdoc/html/templates/type_layout.html b/src/librustdoc/html/templates/type_layout.html index aee96fb8c417..9c62826ccc2e 100644 --- a/src/librustdoc/html/templates/type_layout.html +++ b/src/librustdoc/html/templates/type_layout.html @@ -28,13 +28,11 @@ {% endfor %} {% endif %} - {# This kind of layout error can occur with valid code, e.g. if you try to - get the layout of a generic type such as `Vec`. #} + {# This kind of layout error can occur with valid code, for example + if there are trivial bounds: `struct Foo(str, str) where str: Sized;`. #} {% when Err(LayoutError::Unknown(_)) %}